Skip to content

Trait impls #18447

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 2 commits into from
Nov 4, 2014
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
11 changes: 8 additions & 3 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,10 @@ impl NameBindings {
sp: Span) {
// Merges the module with the existing type def or creates a new one.
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
let module_ = Rc::new(Module::new(parent_link,
def_id,
kind,
external,
is_public));
let type_def = self.type_def.borrow().clone();
match type_def {
Expand Down Expand Up @@ -1372,6 +1375,8 @@ impl<'a> Resolver<'a> {
// Create the module and add all methods.
match ty.node {
TyPath(ref path, _, _) if path.segments.len() == 1 => {
// FIXME(18446) we should distinguish between the name of
// a trait and the name of an impl of that trait.
let mod_name = path.segments.last().unwrap().identifier.name;

let parent_opt = parent.module().children.borrow()
Expand All @@ -1380,8 +1385,8 @@ impl<'a> Resolver<'a> {
// It already exists
Some(ref child) if child.get_module_if_available()
.is_some() &&
child.get_module().kind.get() ==
ImplModuleKind => {
(child.get_module().kind.get() == ImplModuleKind ||
child.get_module().kind.get() == TraitModuleKind) => {
ModuleReducedGraphParent(child.get_module())
}
Some(ref child) if child.get_module_if_available()
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// and `Rc<Baz>`. (Note that it is not a *coherence violation*
// to have impls for both `Bar` and `Baz`, despite this
// ambiguity). In this case, we report an error, listing all
// the applicable impls. The use can explicitly "up-coerce"
// the applicable impls. The user can explicitly "up-coerce"
// to the type they want.
//
// Note that this coercion step only considers actual impls
Expand Down Expand Up @@ -1931,7 +1931,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {

fn all_impls(&self, trait_def_id: ast::DefId) -> Vec<ast::DefId> {
/*!
* Returns se tof all impls for a given trait.
* Returns set of all impls for a given trait.
*/

ty::populate_implementations_for_trait_if_necessary(self.tcx(),
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
let impl_items = self.create_impl_from_item(item);

for associated_trait in associated_traits.iter() {
let trait_ref = ty::node_id_to_trait_ref(
self.crate_context.tcx, associated_trait.ref_id);
let trait_ref = ty::node_id_to_trait_ref(self.crate_context.tcx,
associated_trait.ref_id);
debug!("(checking implementation) adding impl for trait '{}', item '{}'",
trait_ref.repr(self.crate_context.tcx),
token::get_ident(item.ident));
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/typeck/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
let self_ty = ty::lookup_item_type(self.tcx, def_id).ty;
match ty::get(self_ty).sty {
ty::ty_enum(def_id, _) |
ty::ty_struct(def_id, _) => {
ty::ty_struct(def_id, _) |
ty::ty_trait(box ty::TyTrait{ def_id, ..}) => {
if def_id.krate != ast::LOCAL_CRATE {
span_err!(self.tcx.sess, item.span, E0116,
"cannot associate methods with a type outside the \
Expand Down
26 changes: 26 additions & 0 deletions src/test/compile-fail/trait-impl-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 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.

// Test calling methods on an impl for a bare trait. This test checks that the
// trait impl is only applied to a trait object, not concrete types which implement
// the trait.

trait T {}

impl<'a> T+'a {
fn foo(&self) {}
}

impl T for int {}

fn main() {
let x = &42i;
x.foo(); //~ERROR: type `&int` does not implement any method in scope named `foo`
}
24 changes: 24 additions & 0 deletions src/test/compile-fail/trait-impl-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 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.

// Test calling methods on an impl for a bare trait. This test checks trait impls
// must be in the same module as the trait.

mod Foo {
trait T {}
}

mod Bar {
impl<'a> ::Foo::T+'a { //~ERROR: inherent implementations may only be implemented in the same
fn foo(&self) {}
}
}

fn main() {}
36 changes: 36 additions & 0 deletions src/test/run-pass/trait-impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 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.

// Test calling methods on an impl for a bare trait.

static mut COUNT: uint = 1;

trait T {}

impl<'a> T+'a {
fn foo(&self) {
unsafe { COUNT *= 2; }
}
fn bar() {
unsafe { COUNT *= 3; }
}
}

impl T for int {}

fn main() {
let x: &T = &42i;

x.foo();
T::foo(x);
T::bar();

unsafe { assert!(COUNT == 12); }
}