Skip to content

Make object types not implement their associated trait #5087

@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
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions