auto merge of #14974 : Ryman/rust/non_trait_method, r=alexcrichton
Closes #3973.
This commit is contained in:
commit
d6c1b85246
@ -3894,8 +3894,31 @@ fn resolve_trait_reference(&mut self,
|
||||
self.resolve_error(trait_reference.path.span, msg.as_slice());
|
||||
}
|
||||
Some(def) => {
|
||||
debug!("(resolving trait) found trait def: {:?}", def);
|
||||
self.record_def(trait_reference.ref_id, def);
|
||||
match def {
|
||||
(DefTrait(_), _) => {
|
||||
debug!("(resolving trait) found trait def: {:?}", def);
|
||||
self.record_def(trait_reference.ref_id, def);
|
||||
}
|
||||
(def, _) => {
|
||||
self.resolve_error(trait_reference.path.span,
|
||||
format!("`{}` is not a trait",
|
||||
self.path_idents_to_str(
|
||||
&trait_reference.path)));
|
||||
|
||||
// If it's a typedef, give a note
|
||||
match def {
|
||||
DefTy(_) => {
|
||||
self.session.span_note(
|
||||
trait_reference.path.span,
|
||||
format!("`type` aliases cannot \
|
||||
be used for traits")
|
||||
.as_slice());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4021,6 +4044,9 @@ fn resolve_implementation(&mut self,
|
||||
|
||||
this.with_current_self_type(self_type, |this| {
|
||||
for method in methods.iter() {
|
||||
// If this is a trait impl, ensure the method exists in trait
|
||||
this.check_trait_method(&**method);
|
||||
|
||||
// We also need a new scope for the method-specific type parameters.
|
||||
this.resolve_method(MethodRibKind(id, Provided(method.id)),
|
||||
&**method);
|
||||
@ -4030,6 +4056,21 @@ fn resolve_implementation(&mut self,
|
||||
});
|
||||
}
|
||||
|
||||
fn check_trait_method(&self, method: &Method) {
|
||||
// If there is a TraitRef in scope for an impl, then the method must be in the trait.
|
||||
for &(did, ref trait_ref) in self.current_trait_ref.iter() {
|
||||
let method_name = method.ident.name;
|
||||
|
||||
if self.method_map.borrow().find(&(method_name, did)).is_none() {
|
||||
let path_str = self.path_idents_to_str(&trait_ref.path);
|
||||
self.resolve_error(method.span,
|
||||
format!("method `{}` is not a member of trait `{}`",
|
||||
token::get_name(method_name),
|
||||
path_str).as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_module(&mut self, module: &Mod, _span: Span,
|
||||
_name: Ident, id: NodeId) {
|
||||
// Write the implementations in scope into the module metadata.
|
||||
|
@ -784,7 +784,8 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
|
||||
&impl_trait_ref.substs);
|
||||
}
|
||||
None => {
|
||||
tcx.sess.span_err(
|
||||
// This is span_bug as it should have already been caught in resolve.
|
||||
tcx.sess.span_bug(
|
||||
impl_method.span,
|
||||
format!(
|
||||
"method `{}` is not a member of trait `{}`",
|
||||
|
20
src/test/compile-fail/issue-3907-2.rs
Normal file
20
src/test/compile-fail/issue-3907-2.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2013-2014 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.
|
||||
|
||||
// aux-build:issue_3907.rs
|
||||
extern crate issue_3907;
|
||||
|
||||
type Foo = issue_3907::Foo; //~ ERROR: reference to trait
|
||||
|
||||
struct S {
|
||||
name: int
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -11,13 +11,14 @@
|
||||
// aux-build:issue_3907.rs
|
||||
extern crate issue_3907;
|
||||
|
||||
type Foo = issue_3907::Foo; //~ ERROR: reference to trait
|
||||
type Foo = issue_3907::Foo;
|
||||
|
||||
struct S {
|
||||
name: int
|
||||
}
|
||||
|
||||
impl Foo for S { //~ ERROR: `Foo` is not a trait
|
||||
//~^ NOTE: `type` aliases cannot be used for traits
|
||||
fn bar() { }
|
||||
}
|
||||
|
||||
|
@ -8,26 +8,29 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-test
|
||||
|
||||
use std::io;
|
||||
|
||||
struct Point {
|
||||
x: f64,
|
||||
y: f64,
|
||||
}
|
||||
|
||||
impl ToStr for Point { //~ ERROR implements a method not defined in the trait
|
||||
trait NewTrait {
|
||||
fn a(&self) -> String;
|
||||
}
|
||||
|
||||
impl NewTrait for Point {
|
||||
fn new(x: f64, y: f64) -> Point {
|
||||
//~^ ERROR method `new` is not a member of trait `NewTrait`
|
||||
Point { x: x, y: y }
|
||||
}
|
||||
|
||||
fn to_str(&self) -> String {
|
||||
fn a(&self) -> String {
|
||||
format!("({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let p = Point::new(0.0, 0.0);
|
||||
println!("{}", p.to_str());
|
||||
//~^ ERROR unresolved name `Point::new`
|
||||
//~^^ ERROR failed to resolve. Use of undeclared module `Point`
|
||||
println!("{}", p.a());
|
||||
}
|
||||
|
14
src/test/compile-fail/issue-5035-2.rs
Normal file
14
src/test/compile-fail/issue-5035-2.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2013-2014 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.
|
||||
|
||||
trait I {}
|
||||
type K = I; //~ ERROR: reference to trait
|
||||
|
||||
fn main() {}
|
@ -9,6 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
trait I {}
|
||||
type K = I; //~ ERROR: reference to trait
|
||||
type K = I;
|
||||
impl K for int {} //~ ERROR: `K` is not a trait
|
||||
//~^ NOTE: `type` aliases cannot be used for traits
|
||||
fn main() {}
|
||||
|
Loading…
Reference in New Issue
Block a user