Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upTrait bounds are not yet enforced in type definitions #21903
Comments
This comment has been minimized.
This comment has been minimized.
|
At first glance this is probably related to the internal messy-ness of bounds vs. where-clauses. I'm not sure if the predicate constraints for type aliases are propagated correctly. You should be able to use a newtype as a work around:
Seems to work just fine on playground with the newtype: http://is.gd/krOTZv. |
This comment has been minimized.
This comment has been minimized.
|
I would use a newtype but since the type I want to define is a specialized Result type that isn't possible in my case. I didn't really mention that since it is tangential to the bug itself. |
kmcallister
added
A-typesystem
A-traits
labels
Feb 4, 2015
This comment has been minimized.
This comment has been minimized.
|
Looks like warnings are now generated for this case, but not consistently[0]. Should this be a compile-time error instead? [0] #20222 (comment) |
tamird
referenced this issue
Apr 22, 2015
Closed
"Internal error looking up definition" using a type alias with a where clause #20222
This comment has been minimized.
This comment has been minimized.
|
What is the status on trait bounds in type definitions? I worked around it the best I could for combine but it won't be as clean as it could be until bounds are allowed. |
This comment has been minimized.
This comment has been minimized.
|
Where bounds are allowed, they're not checked properly. I'm using this one and it compiles from Rust 1.0 or later pub type MapFn<I, B> where I: Iterator = iter::Map<I, fn(I::Item) -> B>; |
nikomatsakis
added
I-nominated
T-compiler
labels
Dec 15, 2015
This comment has been minimized.
This comment has been minimized.
|
Nominating for discussion. Seems like backcompat hazard we should consider trying to address with a feature gate. |
This comment has been minimized.
This comment has been minimized.
|
Since the bounds provide writing types you couldn't do otherwise, they are very useful. A feature gate would be a breaking change without recourse(?). |
This comment has been minimized.
This comment has been minimized.
|
triage: P-medium I think this might be not that hard to fix though! |
rust-highfive
added
P-medium
and removed
I-nominated
labels
Dec 17, 2015
jonas-schievink
referenced this issue
Jan 12, 2016
Open
Lifetime-polymorphic anonymous function causing compiler panic #30860
This comment has been minimized.
This comment has been minimized.
nixpulvis
commented
Feb 9, 2016
|
Unless I'm missing something, this isn't a huge problem because bad things will still fail to type check right? For example the following doesn't compile. trait Foo {
fn foo(&self) -> u32 {
1
}
}
type Bar<F: Foo> = F;
fn foo(f: Bar<&str>) -> Bar<&str> {
f
}
fn main() {
let bar: Bar<&str> = "";
println!("{:?}", foo(bar.foo()));
} |
This comment has been minimized.
This comment has been minimized.
|
@nixpulvis I think the argument for checking type definitions is analogous to our philosophy about other polymorphic code: we don't do C++ style post template-instantiation type-checking; instead we check the polymorphic code at the definition site (even though both strategies are sound) Or maybe you are just saying the backwards incompatibility hit won't be that bad? (To which I say: famous last words. .. ;) |
This comment has been minimized.
This comment has been minimized.
nixpulvis
commented
Feb 9, 2016
brson
added
E-hard
I-needs-decision
labels
Aug 25, 2016
This comment has been minimized.
This comment has been minimized.
|
So this issue is a regular annoyance. It's worth trying to figure out just what we want to do, however! The key problem is that type aliases are "invisible" to the type checker. You could almost just remove where-clauses from them altogether, but that we need them to resolve associated types in things like Enforcing all type bounds could be tricky, but may well be readily achievable. There is some backwards compatibility to worry about. I guess how we would implement it would be to extend the "item type" associated with a Another option would be to detect if the bound is needed (i.e., consumed by an associated type), and warn only if that is not the case. That would just be accepting that we allow where-clauses here even when they are not needed and will not be unenforced. Doesn't feel very good though. Seems like we might want to start by trying for the "better" fix, and then measuring the impact...? |
Marwes
referenced this issue
Feb 16, 2017
Closed
Make it possible for `combine::primitives::ParseError` to be `std::error::Error` for more range types #86
ncalexan
added a commit
to ncalexan/combine
that referenced
this issue
Feb 17, 2017
ncalexan
added a commit
to ncalexan/combine
that referenced
this issue
Feb 17, 2017
ncalexan
referenced this issue
Feb 17, 2017
Merged
Add map functions for Error<> and Info<> ranges. (#86) #87
This comment has been minimized.
This comment has been minimized.
@nikomatsakis Would it be possible to remove that warning for these cases then? It's quite confusing. |
This comment has been minimized.
This comment has been minimized.
|
@RReverser I agree. I just added a to do item to try and investigate disabling the warnings. |
This comment has been minimized.
This comment has been minimized.
Twey
commented
Mar 15, 2017
|
Workaround: if you're using an associated type on the type parameter, you can replace (Interestingly, even |
This comment has been minimized.
This comment has been minimized.
Yeah, was exactly my problem. Thanks for the workaround, I'll give it a try! |
This comment has been minimized.
This comment has been minimized.
|
@Twey thank you, that did it! |
RReverser
added a commit
to RReverser/serde-xml-rs
that referenced
this issue
Mar 20, 2017
petrochenkov
referenced this issue
Jul 9, 2017
Open
Future-incompatible warnings should always print a warning, even if lints are allowed #34596
Mark-Simulacrum
added
C-future-compatibility
and removed
C-tracking-issue
labels
Jul 22, 2017
bors
added a commit
that referenced
this issue
Dec 13, 2017
bors
added a commit
that referenced
this issue
Dec 13, 2017
bors
added a commit
that referenced
this issue
Dec 13, 2017
bors
added a commit
that referenced
this issue
Dec 14, 2017
bors
added a commit
that referenced
this issue
Dec 14, 2017
This comment has been minimized.
This comment has been minimized.
With #48326 merged, this warning is now a normal lint and can be disabled with However, what I did not realize is that the bounds are actually not entirely ignored -- Given that this bug is unfixed for three years, it seems overly optimistic to expect a proper implementation of enforcing these bounds any time soon. Also, I think the warning is crucial because currently, the compiler accepts code such as the following: use std::cell::Cell;
type SVec<T: Send> = Vec<T>;
fn foo(_x: SVec<&Cell<i32>>) {}
pub fn bar() {
foo(Vec::new());
}This is clearly nonsensical -- a type declared with The best option I can think of currently is to make people write struct Sendable<T: Send>(T);
type MySendable<T> = Sendable<T>; // no error here!So, if type aliases are ever checked for well-formedness, that would require a transition period anyway. |
This comment has been minimized.
This comment has been minimized.
My expectation here has been that we will do the following: (1) Implement lazy normalization (underway) |
This comment has been minimized.
This comment has been minimized.
Yes, that's probably the most forwards compatible thing you can do, and yes it's somewhat surprising (but consistent). I tend to make an alias in practice just so it is shorter (and to not get warnings): type Assoc<T> = <T as Trait>::Assoc;
type SomethingElse<T> = Vec<Assoc<T>>; |
This comment has been minimized.
This comment has been minimized.
Okay, so given that, do you think the approach I took in #48909 makes sense? |
This comment has been minimized.
This comment has been minimized.
|
@RalfJung are you asking if your suggestion to use |
This comment has been minimized.
This comment has been minimized.
Yes. Originally I intended this to be a step towards turning the lint into a hard error eventually, but of course if this gets implemented properly that's even better. :) I can't imagine how to implement this in a nice backwards-compatible way, but well, you seem to have some idea :D |
pgerber
referenced this issue
Mar 17, 2018
Merged
Fix "bounds on generic parameters are ignored in type aliases" #1010
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Mar 23, 2018
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Mar 23, 2018
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Mar 23, 2018
RalfJung
referenced this issue
Mar 28, 2018
Open
Reject bounds in type aliases with edition 2018 #49441
eddyb
referenced this issue
Aug 25, 2018
Closed
Empty bounds lists in where clauses cause the type to not be WF-checked. #53696
eddyb
referenced this issue
Sep 9, 2018
Closed
[WIP] rustc_typeck: ensure type alias bounds are implied by the type being well-formed. #54090
bors
added a commit
that referenced
this issue
Sep 9, 2018
This comment has been minimized.
This comment has been minimized.
|
Any progress here lately? (Trying to have a go at implementing trait aliases here.) |
Marwes commentedFeb 3, 2015
Opening an issue since I could not find any information on when/if this will be enforced. Would be really useful for some generalizing I am trying for parser-combinators which I can't do currently without complicating the API.
Specifically I'd like to use a trait bound in a type definition to access an associated type to avoid passing it seperately but due to this issue I simply get a compiler error.
Simplified code which exhibits the error: