Cleanup error messages for anonymous impl for types not declared in the current module
Followup to RFC 57. Fixes #7607 Fixes #8767 Fixes #12729 Fixes #15060
This commit is contained in:
parent
9a68da7401
commit
bb5807919a
@ -2945,16 +2945,53 @@ impl<'a> Resolver<'a> {
|
||||
match *name_bindings.type_def.borrow() {
|
||||
None => {}
|
||||
Some(ref ty) => {
|
||||
let msg = format!("import `{}` conflicts with type in \
|
||||
this module",
|
||||
token::get_name(name).get());
|
||||
self.session.span_err(import_span, msg.as_slice());
|
||||
match ty.type_span {
|
||||
None => {}
|
||||
Some(span) => {
|
||||
self.session
|
||||
.span_note(span,
|
||||
"conflicting type here")
|
||||
match ty.module_def {
|
||||
None => {
|
||||
let msg = format!("import `{}` conflicts with type in \
|
||||
this module",
|
||||
token::get_name(name).get());
|
||||
self.session.span_err(import_span, msg.as_slice());
|
||||
match ty.type_span {
|
||||
None => {}
|
||||
Some(span) => {
|
||||
self.session
|
||||
.span_note(span,
|
||||
"note conflicting type here")
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(ref module_def) => {
|
||||
match module_def.kind.get() {
|
||||
ImplModuleKind => {
|
||||
match ty.type_span {
|
||||
None => { /* this can't ever happen */ }
|
||||
Some(span) => {
|
||||
let msg = format!("inherent implementations \
|
||||
are only allowed on types \
|
||||
defined in the current module");
|
||||
self.session
|
||||
.span_err(span, msg.as_slice());
|
||||
self.session
|
||||
.span_note(import_span,
|
||||
"import from other module here")
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let msg = format!("import `{}` conflicts with existing \
|
||||
submodule",
|
||||
token::get_name(name).get());
|
||||
self.session.span_err(import_span, msg.as_slice());
|
||||
match ty.type_span {
|
||||
None => {}
|
||||
Some(span) => {
|
||||
self.session
|
||||
.span_note(span,
|
||||
"note conflicting module here")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4610,6 +4647,30 @@ impl<'a> Resolver<'a> {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Check that the current type is indeed a type, if we have an anonymous impl
|
||||
if opt_trait_reference.is_none() {
|
||||
match self_type.node {
|
||||
// TyPath is the only thing that we handled in `build_reduced_graph_for_item`,
|
||||
// where we created a module with the name of the type in order to implement
|
||||
// an anonymous trait. In the case that the path does not resolve to an actual
|
||||
// type, the result will be that the type name resolves to a module but not
|
||||
// a type (shadowing any imported modules or types with this name), leading
|
||||
// to weird user-visible bugs. So we ward this off here. See #15060.
|
||||
TyPath(ref path, _, path_id) => {
|
||||
match self.def_map.borrow().find(&path_id) {
|
||||
// FIXME: should we catch other options and give more precise errors?
|
||||
Some(&DefMod(_)) => {
|
||||
self.resolve_error(path.span, "inherent implementations are not \
|
||||
allowed for types not defined in \
|
||||
the current module.");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_item(&self, ident: Ident, span: Span) {
|
||||
|
23
src/test/compile-fail/issue-12729.rs
Normal file
23
src/test/compile-fail/issue-12729.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
pub struct Foo;
|
||||
|
||||
mod bar {
|
||||
use Foo;
|
||||
|
||||
impl Foo { //~ERROR inherent implementations are only allowed on types defined in the current module
|
||||
fn baz(&self) {}
|
||||
}
|
||||
}
|
||||
fn main() {}
|
||||
|
22
src/test/compile-fail/issue-7607-1.rs
Normal file
22
src/test/compile-fail/issue-7607-1.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
struct Foo {
|
||||
x: int
|
||||
}
|
||||
|
||||
impl Fo { //~ERROR inherent implementations are not allowed for types not defined in the current module.
|
||||
fn foo() {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
26
src/test/compile-fail/issue-7607-2.rs
Normal file
26
src/test/compile-fail/issue-7607-2.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
pub mod a {
|
||||
pub struct Foo { a: uint }
|
||||
}
|
||||
|
||||
pub mod b {
|
||||
use a::Foo;
|
||||
impl Foo { //~ERROR inherent implementations are only allowed on types defined in the current module
|
||||
fn bar(&self) { }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() { }
|
||||
|
||||
|
18
src/test/compile-fail/issue-8767.rs
Normal file
18
src/test/compile-fail/issue-8767.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
impl B { //~ERROR inherent implementations are not allowed for types not defined in the current module.
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
@ -8,8 +8,9 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// FIXME(#8767) bad error message; Option is not a module
|
||||
impl<T> Option<T> { //~ERROR found module name used as a type
|
||||
// ignore-tidy-linelength
|
||||
|
||||
impl<T> Option<T> { //~ERROR inherent implementations are not allowed for types not defined in the current module.
|
||||
pub fn foo(&self) { }
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user