Skip to content

Make object types not implement their associated trait #5087

Closed
@nikomatsakis

Description

@nikomatsakis

Currently we have some rather complex rules for when an object type @T (or &T etc) for a trait T implements the trait T. I think we should just say that @T does not implement T.

We can instead add a deriving mode #[deriving_self(managed|borrowed|owned)] to derive an implementation of T for @T, &T, or ~T.

Problems that this avoids

There are a number of unsoundness issues that can result from object types implementing their associated trait. Consider the following examples:

fn foo<T: Eq>(x: &T, y: &T) { ... x.eq(y) ... }
foo::<@Eq>(1 as @Eq, @"hi" as @Eq) // now we are comparing 1.eq("hi")!

trait AtFoo { fn foo(@self, ...) { ... } }
fn bar<T: AtFoo>(x: @T) { x.foo(); }
bar::<~AtFoo>(@(x as ~AtFoo)) // now we are calling `bar()` with a `~Foo` receiver!

trait MakeMe { fn foo() -> Self { ... } }
fn bar<T: MakeMe>(x: T) { ... let y = MakeMe::foo(); ... }
bar::<@MakeMe>(1 as @MakeMe); // now x has type @MakeMe but y has type int

We can come up with rules that prevent these examples, but those rules ultimately get quite complex. Simply saying that @T does not implement T avoids all these problems. Then we can add a deriving rule. All of the scenarios above would result in a type check violation when you tried to actually write out that impl.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions