Skip to content
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

Well-formedness of type parameter defaults is not checked #46669

Closed
leoyvens opened this issue Dec 11, 2017 · 0 comments · Fixed by #46785
Closed

Well-formedness of type parameter defaults is not checked #46669

leoyvens opened this issue Dec 11, 2017 · 0 comments · Fixed by #46785
Labels
A-trait-system Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@leoyvens
Copy link
Contributor

leoyvens commented Dec 11, 2017

This compiles:

struct Foo<T:Copy=String>(T);

fn main() { }

This does not:

struct Foo<T:Copy=String>(T);

fn main() {
    let a: Foo;
}

Even though it's stable, we should probably phase out writing badly formed defaults in declarations.

We also don't check that a dependent default actually implements a given trait when using associated items:

struct Bar<A, T=<A as Iterator>::Item>(A, T);

Will compile. The default being applied is conditional on A implementing Iterator. May be useful for some hacks but seems bogus.

Edit:
We don't even check totally bogus stuff such as:

struct Foo<T, U: FromIterator<T>>(T, U);
struct Bar<Z = Foo<i32, i32>>(Z);
@leoyvens leoyvens changed the title Type parameter defaults do not check bounds at declaration. Well-formedness of type parameter defaults is not checked. Dec 12, 2017
@leoyvens leoyvens changed the title Well-formedness of type parameter defaults is not checked. Well-formedness of type parameter defaults is not checked Dec 12, 2017
@pietroalbini pietroalbini added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-trait-system Area: Trait system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 30, 2018
bors added a commit that referenced this issue Feb 19, 2018
…, r=<try>

[Underspecified semantics] Type check defaults at declaration.

Fixes  #46669. See the test for code that compiles on stable but will no longer compile. This falls under a "Underspecified language semantics" fix. **Needs crater**.

On type and trait declarations, we currently allow anything that name checks as a type parameter default. That allows the user to write a default that can never be applied, or even a default that may conditionally be applied depending on the type of another parameter. Mostly this just defers the error to use sites, but also allows clever hacks such as `Foo<T, U = <T as Iterator>::Item>` where `U` will be able to apply it's default only when `T: Iterator`. Maybe that means this bug is a feature, but it's a fiddly behaviour that seems undesirable.

This PR validates defaults at declaration sites by ensuring all predicates on the parameter are valid for the default. With the exception of `Self: Sized` which we don't want to check to allow things like `trait Add<RHS = Self>`.
bors added a commit that referenced this issue Mar 1, 2018
…, r=nikomatsakis

[Underspecified semantics] Type check defaults at declaration.

Fixes  #46669. See the test for code that compiles on stable but will no longer compile. This falls under a "Underspecified language semantics" fix. **Needs crater**.

On type and trait declarations, we currently allow anything that name checks as a type parameter default. That allows the user to write a default that can never be applied, or even a default that may conditionally be applied depending on the type of another parameter. Mostly this just defers the error to use sites, but also allows clever hacks such as `Foo<T, U = <T as Iterator>::Item>` where `U` will be able to apply it's default only when `T: Iterator`. Maybe that means this bug is a feature, but it's a fiddly behaviour that seems undesirable.

This PR validates defaults at declaration sites by ensuring all predicates on the parameter are valid for the default. With the exception of `Self: Sized` which we don't want to check to allow things like `trait Add<RHS = Self>`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants