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 upTracking Issue for RFC 213: Default Type Parameter Fallback #27336
Comments
jroesch
self-assigned this
Jul 27, 2015
steveklabnik
added
the
B-RFC-approved
label
Jul 29, 2015
alexcrichton
added
the
T-lang
label
Aug 11, 2015
nikomatsakis
added
the
B-unstable
label
Aug 14, 2015
This comment has been minimized.
This comment has been minimized.
|
What is the status of this? |
This comment has been minimized.
This comment has been minimized.
pnkfelix
added
the
I-nominated
label
Dec 1, 2015
This comment has been minimized.
This comment has been minimized.
|
This doesn't seem to be working properly. #![crate_type = "lib"]
#![feature(default_type_parameter_fallback)]
trait A<T = Self> {
fn a(t: &T) -> Self;
}
trait B<T = Self> {
fn b(&self) -> T;
}
impl<U, T = U> B<T> for U
where T: A<U>
{
fn b(&self) -> T {
T::a(self)
}
}
struct X(u8);
impl A for X {
fn a(x: &X) -> X {
X(x.0)
}
}
fn f(x: &X) {
x.b(); // ok
}
fn g(x: &X) {
let x = x.b();
x.0; // error: the type of this value must be known in this context
} |
This comment has been minimized.
This comment has been minimized.
|
@mahkoh there is a necessary patch that hasn't gotten rebased since I stopped my summer internship. I've been unfortunately busy with real life stuff, looks like @nikomatsakis has plans for landing a slightly different version according to a recent post of his on the corresponding documentation issue for this feature. |
nagisa
referenced this issue
Jan 8, 2016
Merged
Revamp the support for "future incompatible" lints #30787
gkoz
referenced this issue
Jan 13, 2016
Open
Type parameters better have defaults in the presence of Option #143
bluss
referenced this issue
Jan 18, 2016
Merged
Feature gate defaulted type parameters appearing outside of types #30724
aturon
removed
the
I-nominated
label
Jan 28, 2016
aturon
assigned
nikomatsakis
and unassigned
jroesch
Jan 28, 2016
This was referenced Jan 28, 2016
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis I know the lang team didn't see any future in this feature, will you put that on record in the issue One example where this feature seems to be the only way out is the following concrete example of API evolution in libstd.
|
This comment has been minimized.
This comment has been minimized.
|
@bluss I HAVE been dubious of this feature, but I'm been slowly reconsidering. @aturon is supposed to be doing some exploration of this whole space and writing up some detailed thoughts. I actually started rebasing @jroesch's dead branch to implement the desired semantics and making some progress there too, but I've been distracted. One advantage of finishing up the impl is that it would let us experiment with extensions like the one you describe to see how backwards compatible they truly are -- one problem with fallback is that it is not ACTUALLY backwards compatible, because of the possibility of competing incompatible fallbacks. |
This comment has been minimized.
This comment has been minimized.
|
That said I still have my doubts :) |
This comment has been minimized.
This comment has been minimized.
|
Another example where this could be useful -- basically the same example as petgraph -- is adding allocators to collections in some smooth way. |
This comment has been minimized.
This comment has been minimized.
|
What are the drawbacks to turning this on? It seems to mainly make things compile that otherwise cannot infer enough type information. |
This comment has been minimized.
This comment has been minimized.
|
I have a pretty good use for this too. It's basically what @bluss mentioned, adding new types to an |
This comment has been minimized.
This comment has been minimized.
|
Is the only issue with this the interaction with numeric fallback? I like default type parameters a lot. I often use them when I parameterize a type which has only one production instantiation, for mocking and to enforce bondaries. Its inconsistent and for me unpleasant that defaults don't work for the type parameters of functions. |
nikomatsakis
referenced this issue
Jan 4, 2017
Closed
Type parameter default not respected with enums #24857
Gankro
referenced this issue
Apr 10, 2017
Merged
Use shorter synonym for Hashmap::with_hasher(Default::default()) #1098
bors-servo
added a commit
to servo/webrender
that referenced
this issue
Apr 10, 2017
This comment has been minimized.
This comment has been minimized.
|
It's really unfortunate that this is blocking #32838. Is there anything I can do to help push this forward, outside of implementation work? |
This comment has been minimized.
This comment has been minimized.
|
I don't think it's blocking that. We can always just newtype all of collections in std, and move hashmap into collections while we are at it. It's an ugly solution, but only a temporary once. The allocator traits are far enough behind schedule that we should seriously consider it. |
This comment has been minimized.
This comment has been minimized.
|
@Gankro I think we're still sort of in need of a good survey of the space of ideas and a nice summary. That would be helpful. |
Mark-Simulacrum
added
C-tracking-issue
and removed
C-enhancement
C-feature-request
labels
Jul 22, 2017
petrochenkov
referenced this issue
Aug 17, 2017
Open
Is automatic insertion of type inference placeholders possible? #43942
This comment has been minimized.
This comment has been minimized.
|
I have a few more cases where this is really useful. In particular I have a situation where I have a generic function that requires type inference for the return value. However if there is no user of the return value it requires annotations even though I would have perfectly sensible defaults that then get optimized away. Think of it like this: // currently required
let _: () = my_generic_function()?;
// with a unit default
my_generic_function()?; |
This comment has been minimized.
This comment has been minimized.
|
I'm no expert but I'll try to summarize and contribute. We want to use type defaults to inform inference. However we may get multiple defaults that could apply to an inference variable, resulting in a conflict. Also new defaults may be added in the future, causing conflicts where there was none. @eddyb proposes the conservative approach of erroing on conflict and erroing when trying to apply a default to a type with no default, for future-proofing. The consequence is that all defaults must be present and must agree to be applied. Let's take the reasonable and useful example by @joshtriplett. It would not work because it's trying to unify So I propose that local defaults trump type defaults. So fn and impl defaults would take precedence over the default on the type, meaning that any future conflict between Note that this is limited to literals, if the value came from another fn as in: fn noner<T>() -> Option<T> { None }
fn main() {
// func is same as in original example.
func(noner());
}Then we are back to an error. This a small yet useful extension, together with the Edit: If we give fns and impls preference on the defaults, then we should not inherit the default from the type as that would defeat the point of adding the default being non-breaking. Edit 2:
Given a set of type variables in context that could be unified by a default, can't we order those variables by the order they are introduced? And then consider them in order, trying their defaults and failing at the first variable with no default. |
This was referenced Nov 23, 2017
leodasvacas
referenced this issue
Jan 13, 2018
Closed
Generalise slice::contains over PartialEq #46934
leodasvacas
referenced this issue
Feb 3, 2018
Closed
Default type parameter fallback revisited #2321
varkor
referenced this issue
Apr 10, 2018
Merged
Move Range*::contains to a single default impl on RangeBounds #49130
eddyb
referenced this issue
Jul 13, 2018
Open
Type inference fails in light of generic type aliases with default parameter. #50822
This comment has been minimized.
This comment has been minimized.
DoumanAsh
commented
Jul 17, 2018
|
Found this issue when I was looking into RFC. I noticed recently a problem for myself when I have default type paramer, but my impl is generic.
I wonder if it would be sensible to allow impl blocks to have default type parameters while retaining ability to specify trait boundry. e.g. pub trait MyTrait {}
struct MyStruct;
impl MyTrait for MyStruct;
struct API<M: MyStruct> {
....
}
impl<M: MyTrait=MyStruct> for API<M> {
pub fn new() -> Self<M> {
}
}I may understand reasoning for impl blocks to overshadow default parameter when invoking |
SimonSapin
referenced this issue
Feb 17, 2019
Open
Tracking issue for custom allocators in standard collections #42774
This comment has been minimized.
This comment has been minimized.
lachlansneff
commented
Feb 17, 2019
|
Could this be fast tracked? Having better type inference would allow better user-experience for collections with custom allocators. #42774 (comment) |
This comment has been minimized.
This comment has been minimized.
|
The proposal is in currently in a zombie state due to disagreements among the lang-team over how to resolve issues that were discovered during implementation. No progress has been made as it is otherwise regarded as low priority. |
This comment has been minimized.
This comment has been minimized.
|
Maybe that priority should be re-evaluated? I think this is blocking various library improvements such as |
This comment has been minimized.
This comment has been minimized.
|
I'm not aware of any reason custom allocators would be blocked on default-affects-inference. They can be added backwards-compatibly in the same way hashers currently work -- ::new and friends would hardcode the default, and Default::default/with_allocator would be properly generic. |
This comment has been minimized.
This comment has been minimized.
|
Is this the same issue I'm running into here? pub struct Foo<T: Default = u64>(T);
impl<T: Default> Foo<T> {
pub fn make() -> Foo<T> {
Foo(T::default())
}
}
fn main() {
// error[E0283]: type annotations required: cannot resolve `_: std::default::Default`
let foo = Foo::make();
} |
This comment has been minimized.
This comment has been minimized.
|
Yes. |
This comment has been minimized.
This comment has been minimized.
The default hasher I'd also like to define collections prior to the notion of global allocation being introduced, which would piggyback on the solution for |
jroesch commentedJul 27, 2015
This is a tracking issue for RFC 213.
The initial implementation of this feature has landed.
cc @nikomatsakis