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

Unsized types allowed in trait method declarations and default type parameters #19182

Closed
apasel422 opened this issue Nov 21, 2014 · 7 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-DSTs Area: Dynamically-sized types (DSTs) A-trait-system Area: Trait system

Comments

@apasel422
Copy link
Contributor

It appears that the rules for where unsized types may appear are inconsistently enforced. This doesn't appear to cause unsoundness, because the items are unusable, but an early error would probably be helpful.

The following snippets compile with rustc 0.13.0-nightly (399ff259e 2014-11-20 00:27:07 +0000):

trait Foo {
    fn bar(a: [u8]);
    fn baz() -> [u8];
}

Attempting to implement Foo or provide a default implementation for bar or baz results in the expected compilation error per #13376.

#![feature(default_type_params)]
trait Foo<T = [u8]> {}
struct Bar<T = [u8]>;
enum Baz<T = [u8]> {}
fn quux<T = [u8]>() {}

Note that T is not declared Sized?. Attempting to explicitly instantiate this type parameter with an unsized type results in the expected compilation error for each of these cases.

@apasel422 apasel422 changed the title Trait method declarations permit unsized parameters Unsized types allowed in trait method declarations and default type parameters Nov 21, 2014
@apasel422
Copy link
Contributor Author

This is also the case for supertrait bounds:

trait Foo<T> {}
trait Bar : Foo<[u8]> {}

@apasel422
Copy link
Contributor Author

This also compiles, though foo is not callable:

fn foo(_: [u8]) {}

@apasel422
Copy link
Contributor Author

Another one (Vec's type parameter is sized):

type Foo = Vec<[u8]>;

@ftxqxd
Copy link
Contributor

ftxqxd commented Nov 22, 2014

There are actually two issues here, as I see it:

  1. Bounds on type parameters are not checked in many places. This includes default type parameters of functions and types (e.g., fn foo<T: Copy = Box<int>>()), supertrait parameters (e.g., trait Foo<T: Copy> {} trait Bar: Foo<Box<int>> {}), and type aliases (e.g., struct Foo<T: Copy>; type Bar = Foo<Box<int>>;). The case encountered in this issue is with Sized, which is an implicit bound on all type parameters that aren’t preceded by Sized?, but this actually applies to all trait bounds.
  2. Unsized types are not disallowed in function parameter and return types (e.g., fn foo(_: [u8]) -> [u8]). This applies to trait methods, too.

Perhaps this issue should be split into two issues, then? I think this issue should be repurposed for the DST-related part (part 2), and a new issue should be created for the other part (unless such an issue already exists).

@arielb1
Copy link
Contributor

arielb1 commented Jul 9, 2015

@nikomatsakis claims this is intentional.

@arielb1
Copy link
Contributor

arielb1 commented Jul 9, 2015

closing.

@arielb1 arielb1 closed this as completed Jul 9, 2015
@ibraheemdev
Copy link
Member

@nikomatsakis Why is this intentional behavior? The following code still compiles on Rust 1.50:

trait Foo {
    fn bar(a: [u8]);
    fn baz() -> [u8];
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-DSTs Area: Dynamically-sized types (DSTs) A-trait-system Area: Trait system
Projects
None yet
Development

No branches or pull requests

5 participants