Skip to content

add separate errors for out-of-place associated consts and types #27120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,5 +305,7 @@ register_diagnostics! {
E0432, // unresolved import
E0433, // failed to resolve
E0434, // can't capture dynamic environment in a fn item
E0435 // attempt to use a non-constant value in a constant
E0435, // attempt to use a non-constant value in a constant
E0437, // type is not a member of trait
E0438, // const is not a member of trait
}
35 changes: 27 additions & 8 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ pub enum ResolutionError<'a> {
UndeclaredAssociatedType,
/// error E0407: method is not a member of trait
MethodNotMemberOfTrait(Name, &'a str),
/// error E0437: type is not a member of trait
TypeNotMemberOfTrait(Name, &'a str),
/// error E0438: const is not a member of trait
ConstNotMemberOfTrait(Name, &'a str),
/// error E0408: variable `{}` from pattern #1 is not bound in pattern
VariableNotBoundInPattern(Name, usize),
/// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
Expand Down Expand Up @@ -220,6 +224,18 @@ fn resolve_error<'b, 'a:'b, 'tcx:'a>(resolver: &'b Resolver<'a, 'tcx>, span: syn
method,
trait_);
},
ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
span_err!(resolver.session, span, E0437,
"type `{}` is not a member of trait `{}`",
type_,
trait_);
},
ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
span_err!(resolver.session, span, E0438,
"const `{}` is not a member of trait `{}`",
const_,
trait_);
},
ResolutionError::VariableNotBoundInPattern(variable_name, pattern_number) => {
span_err!(resolver.session, span, E0408,
"variable `{}` from pattern #1 is not bound in pattern #{}",
Expand Down Expand Up @@ -2385,10 +2401,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
for impl_item in impl_items {
match impl_item.node {
ConstImplItem(..) => {
// If this is a trait impl, ensure the method
// If this is a trait impl, ensure the const
// exists in trait
this.check_trait_item(impl_item.ident.name,
impl_item.span);
impl_item.span,
|n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
this.with_constant_rib(|this| {
visit::walk_impl_item(this, impl_item);
});
Expand All @@ -2397,7 +2414,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// If this is a trait impl, ensure the method
// exists in trait
this.check_trait_item(impl_item.ident.name,
impl_item.span);
impl_item.span,
|n, s| ResolutionError::MethodNotMemberOfTrait(n, s));

// We also need a new scope for the method-
// specific type parameters.
Expand All @@ -2410,10 +2428,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
});
}
TypeImplItem(ref ty) => {
// If this is a trait impl, ensure the method
// If this is a trait impl, ensure the type
// exists in trait
this.check_trait_item(impl_item.ident.name,
impl_item.span);
impl_item.span,
|n, s| ResolutionError::TypeNotMemberOfTrait(n, s));

this.visit_ty(ty);
}
Expand All @@ -2426,15 +2445,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
});
}

fn check_trait_item(&self, name: Name, span: Span) {
fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
where F: FnOnce(Name, &str) -> ResolutionError {
// If there is a TraitRef in scope for an impl, then the method must be in the trait.
if let Some((did, ref trait_ref)) = self.current_trait_ref {
if !self.trait_item_map.contains_key(&(name, did)) {
let path_str = path_names_to_string(&trait_ref.path, 0);
resolve_error(self,
span,
ResolutionError::MethodNotMemberOfTrait(name,
&*path_str));
err(name, &*path_str));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(associated_consts)]

trait A { }

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

Expand Down