Skip to content

Commit ce856a5

Browse files
committed
add separate errors for out-of-place associated consts and types
Previously, these would both be labeled as methods.
1 parent a27fed7 commit ce856a5

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

src/librustc_resolve/diagnostics.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -305,5 +305,7 @@ register_diagnostics! {
305305
E0432, // unresolved import
306306
E0433, // failed to resolve
307307
E0434, // can't capture dynamic environment in a fn item
308-
E0435 // attempt to use a non-constant value in a constant
308+
E0435, // attempt to use a non-constant value in a constant
309+
E0437, // type is not a member of trait
310+
E0438, // const is not a member of trait
309311
}

src/librustc_resolve/lib.rs

+27-8
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ pub enum ResolutionError<'a> {
123123
UndeclaredAssociatedType,
124124
/// error E0407: method is not a member of trait
125125
MethodNotMemberOfTrait(Name, &'a str),
126+
/// error E0437: type is not a member of trait
127+
TypeNotMemberOfTrait(Name, &'a str),
128+
/// error E0438: const is not a member of trait
129+
ConstNotMemberOfTrait(Name, &'a str),
126130
/// error E0408: variable `{}` from pattern #1 is not bound in pattern
127131
VariableNotBoundInPattern(Name, usize),
128132
/// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
@@ -220,6 +224,18 @@ fn resolve_error<'b, 'a:'b, 'tcx:'a>(resolver: &'b Resolver<'a, 'tcx>, span: syn
220224
method,
221225
trait_);
222226
},
227+
ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
228+
span_err!(resolver.session, span, E0437,
229+
"type `{}` is not a member of trait `{}`",
230+
type_,
231+
trait_);
232+
},
233+
ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
234+
span_err!(resolver.session, span, E0438,
235+
"const `{}` is not a member of trait `{}`",
236+
const_,
237+
trait_);
238+
},
223239
ResolutionError::VariableNotBoundInPattern(variable_name, pattern_number) => {
224240
span_err!(resolver.session, span, E0408,
225241
"variable `{}` from pattern #1 is not bound in pattern #{}",
@@ -2385,10 +2401,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
23852401
for impl_item in impl_items {
23862402
match impl_item.node {
23872403
ConstImplItem(..) => {
2388-
// If this is a trait impl, ensure the method
2404+
// If this is a trait impl, ensure the const
23892405
// exists in trait
23902406
this.check_trait_item(impl_item.ident.name,
2391-
impl_item.span);
2407+
impl_item.span,
2408+
|n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
23922409
this.with_constant_rib(|this| {
23932410
visit::walk_impl_item(this, impl_item);
23942411
});
@@ -2397,7 +2414,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
23972414
// If this is a trait impl, ensure the method
23982415
// exists in trait
23992416
this.check_trait_item(impl_item.ident.name,
2400-
impl_item.span);
2417+
impl_item.span,
2418+
|n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
24012419

24022420
// We also need a new scope for the method-
24032421
// specific type parameters.
@@ -2410,10 +2428,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
24102428
});
24112429
}
24122430
TypeImplItem(ref ty) => {
2413-
// If this is a trait impl, ensure the method
2431+
// If this is a trait impl, ensure the type
24142432
// exists in trait
24152433
this.check_trait_item(impl_item.ident.name,
2416-
impl_item.span);
2434+
impl_item.span,
2435+
|n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
24172436

24182437
this.visit_ty(ty);
24192438
}
@@ -2426,15 +2445,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
24262445
});
24272446
}
24282447

2429-
fn check_trait_item(&self, name: Name, span: Span) {
2448+
fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
2449+
where F: FnOnce(Name, &str) -> ResolutionError {
24302450
// If there is a TraitRef in scope for an impl, then the method must be in the trait.
24312451
if let Some((did, ref trait_ref)) = self.current_trait_ref {
24322452
if !self.trait_item_map.contains_key(&(name, did)) {
24332453
let path_str = path_names_to_string(&trait_ref.path, 0);
24342454
resolve_error(self,
24352455
span,
2436-
ResolutionError::MethodNotMemberOfTrait(name,
2437-
&*path_str));
2456+
err(name, &*path_str));
24382457
}
24392458
}
24402459
}

src/test/compile-fail/trait-impl-can-not-have-untraitful-methods.rs renamed to src/test/compile-fail/trait-impl-can-not-have-untraitful-items.rs

+4
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(associated_consts)]
12+
1113
trait A { }
1214

1315
impl A for isize {
16+
const BAR: () = (); //~ ERROR const `BAR` is not a member of trait `A`
17+
type Baz = (); //~ ERROR type `Baz` is not a member of trait `A`
1418
fn foo(&self) { } //~ ERROR method `foo` is not a member of trait `A`
1519
}
1620

0 commit comments

Comments
 (0)