Support assoc type defaults for assoc type constraints of trait objects#152959
Support assoc type defaults for assoc type constraints of trait objects#152959ShoyuVanilla wants to merge 1 commit intorust-lang:mainfrom
Conversation
|
HIR ty lowering was modified cc @fmease |
|
r? @jackh726 rustbot has assigned @jackh726. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
1736f20 to
2c10ecf
Compare
| type ChildKey; | ||
| type Children = dyn Index<Self::ChildKey, Output = dyn Hierarchy>; | ||
| //~^ ERROR: the value of the associated types | ||
| //~^ ERROR: cycle detected when computing type of `Hierarchy::Children` |
There was a problem hiding this comment.
The cycle here is unfortunate but I think this might be inevitable 🤔
| .into_iter() | ||
| .filter_map(|key @ (def_id, _)| { | ||
| if let Some(&assoc) = projection_bounds.get(&key) { | ||
| .filter_map(|(item, trait_ref)| { |
There was a problem hiding this comment.
Could you please also update the large comment above. I'm referring to the part where it says The user has to constrain all associated types & consts via bindings unless the corresponding associated item has a where Self: Sized clause.. Could you update it to say sth. along the lines of […] unless […] has a […] clause or it has a default value which we would then pick.
Thanks!
There was a problem hiding this comment.
Could you please also add a corresponding test for type-level associated constants (feature min_generic_const_args (mGCA))? Please put it into tests/ui/const-generics/associated-const-bindings/ and name it something like dyn-compat-assoc-const-defaults.rs following the established naming convention.
It should look something like:
// Type associated consts needn't be specified in the trait object type
// if they have a default in which case we use said default.
//@ check-pass
#![feature(min_generic_const_args, associated_type_defaults)]
#![expect(incomplete_features)]
trait Trait {
type const N: usize = 1;
}
fn main() {
// `Trait::N` defaults to `1`.
let _: dyn Trait;
let _: [(); <dyn Trait as Trait>::N] = [(); 1];
}(The the phrasing of the description is admittedly rather awkward, feel free to improve it)
(I've intentionally proactively added associated_type_defaults since that will become necessary for such type-level assoc consts once PR #152385 is merged.)
| if has_default { | ||
| Some(trait_ref.map_bound(|trait_ref| ty::ProjectionPredicate { | ||
| projection_term: ty::AliasTerm::new_from_args(tcx, def_id, trait_ref.args), | ||
| term: tcx.type_of(def_id).instantiate(tcx, trait_ref.args).into(), |
There was a problem hiding this comment.
I'm not entirely sure if your current approach can handle the following code that was suggested in similar form in the RFC:
#![feature(associated_type_defaults)]
trait Trait {
type T = Self::U;
type U;
}
fn main() {
let _: dyn Trait<U = ()>; // `Trait::T` should default to `()`
}I have a hunch that this might not work right now but I might be mistaken. I think this will get rejected with the value of associated type T must be specified similar to:
trait Trait: SuperTrait<T = Self::U> { type U; }
trait SuperTrait { type T; }
fn main() {
let _: dyn Trait<U = ()>;
//~^ ERROR the value of the associated type `T` in `SuperTrait` must be specified
}In any case, encapsulating this as a UI test would be nice I think.
As stated in https://rust-lang.github.io/rfcs/2532-associated-type-defaults.html#trait-objects
cc: #29661, the fourth checkbox; "Implement the changes to object types specified in the RFC"