-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Implement feature(more_qualified_paths)
#19956
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
base: master
Are you sure you want to change the base?
Conversation
crates/hir-ty/src/infer.rs
Outdated
@@ -1731,6 +1731,88 @@ impl<'db> InferenceContext<'db> { | |||
|
|||
self.resolve_variant_on_alias(ty, unresolved, mod_path) | |||
} | |||
TypeNs::TraitId(_trait_id) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mostly copied from the SelfType
branch above and this feels very weird. For example the loop always does a single iteration...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loop does not always do a single iteration, in the case Self::AssocType::EnumVariant
it does two. However it seems you copied that incorrectly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rrright. The reason I copied it like that is that I couldn't find a way to get the type (E
in <E as Trait>::Assoc::ES
) for the ty
variable on first iteration.
I found a way to get the type, but you'll probably know a better one ^^'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... It seems your logic should indeed be different from Self
, and you don't need a loop. Since there is no sense to code like Trait::EnumVariant
, you can have straight control flow: lower assoc types (lower_partly_resolved_path()
, but it expects no unresolved segments so you may need to adapt it or ignore_last_segment()
), then check if you have an addition segment, in which case try to resolve an enum variant from the type (ty.as_adt()
then extract an enum out of it).
38a3d65
to
e2710df
Compare
What I can't so far figure out is how to make this work for enums. Example: enum E {
ES { a: u32 },
ET(u32),
}
impl Trait for E {
type Assoc = Self;
}
let <E>::ES { a } = (<E>::ES { a: 0 }) else { panic!() };
let <E>::ET(a) = <E>::ET(0) else { panic!() };
let <E as Trait>::Assoc::ES { a } = (<E as Trait>::Assoc::ES { a: 0 }) else { panic!() };
let <E as Trait>::Assoc::ET(a) = <E as Trait>::Assoc::ET(0) else { panic!() }; Out of all these r-a can only resolve |
The reason To resolve if let Some(type_anchor) = path.type_anchor() {
let segments = path.segments();
if segments.len() != 1 {
return (self.err_ty(), None);
}
let ty = ctx.lower_ty(type_anchor);
if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
let enum_data = self.db.enum_variants(id);
if let Some(variant) = enum_data.variant(segments.first().unwrap().name) {
// FIXME: Report error if there are generics on the variant.
return (ty, Some(variant.into()));
}
} else {
// FIXME: Report an error.
return (self.err_ty(), None);
}
} Also, I'll be happy if you could deduplicate the code for handling |
e2710df
to
da7c176
Compare
Don't be afraid to ask for help should you need it! |
fab04fe
to
1fd0369
Compare
Specifically, this allows the following patterns and expressions which were not allowed before: ```rust let <T as Trait>::Assoc { a } = <T as Trait>::Assoc { a: 0 }; let (<E as Trait>::Assoc::ES { a } | <E as Trait>::Assoc::ET(a)) = <E as Trait>::Assoc::ES { a: 0 }; let (<E>::ES { a } | <E>::ET(a)) = <E>::ES { a: 0 }; ```
1fd0369
to
64f9379
Compare
@ChayimFriedman2 thanks for your advise! I think I was able to implement the feature in a way which doesn't look that bad ^^' Do you know where I could add tests for this? |
crates/hir-ty/src/tests/traits.rs, you can look at existing tests there. |
This probably needs some adjustment for pattern path completions as well. Not necessary for this PR, just a note, can give pointers if you want to add that to this PR though. Seems like we complete the |
@ChayimFriedman2 I'm currently a bit stuck. While adding tests I figured out that I can check if the type ancor is |
Use |
Example: