Skip to content

Commit

Permalink
Auto merge of #13339 - lowr:patch/change-generic-param-order, r=Veykril
Browse files Browse the repository at this point in the history
fix: treat enum variants as generic item on their own

Fixup for #13335

It turns out I tried to merge two procedures into one utility function without noticing the incompatibility.

This time I *did* run analysis-stats on the four crates and confirmed it doesn't crash and this patch doesn't cause regression.
  • Loading branch information
bors committed Oct 3, 2022
2 parents 5bd98e3 + e0a161b commit 974caaf
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
4 changes: 1 addition & 3 deletions crates/hir-ty/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,7 @@ impl TyBuilder<()> {
parent_subst: Option<Substitution>,
) -> TyBuilder<()> {
let generics = generics(db.upcast(), def.into());
// FIXME: this assertion should hold but some adjustment around
// `ValueTyDefId::EnumVariantId` is needed.
// assert!(generics.parent_generics().is_some() == parent_subst.is_some());
assert!(generics.parent_generics().is_some() == parent_subst.is_some());
let params = generics
.iter_self()
.map(|(id, data)| match data {
Expand Down
18 changes: 11 additions & 7 deletions crates/hir-ty/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,22 +653,26 @@ impl<'a> TyLoweringContext<'a> {
infer_args: bool,
) -> Substitution {
let last = path.segments().last().expect("path should have at least one segment");
let generic_def = resolved.to_generic_def_id();
let segment = match resolved {
ValueTyDefId::EnumVariantId(_) => {
let (segment, generic_def) = match resolved {
ValueTyDefId::FunctionId(it) => (last, Some(it.into())),
ValueTyDefId::StructId(it) => (last, Some(it.into())),
ValueTyDefId::UnionId(it) => (last, Some(it.into())),
ValueTyDefId::ConstId(it) => (last, Some(it.into())),
ValueTyDefId::StaticId(_) => (last, None),
ValueTyDefId::EnumVariantId(var) => {
// the generic args for an enum variant may be either specified
// on the segment referring to the enum, or on the segment
// referring to the variant. So `Option::<T>::None` and
// `Option::None::<T>` are both allowed (though the former is
// preferred). See also `def_ids_for_path_segments` in rustc.
let len = path.segments().len();
let penultimate = len.checked_sub(2).and_then(|idx| path.segments().get(idx));
match penultimate {
let segment = match penultimate {
Some(segment) if segment.args_and_bindings.is_some() => segment,
_ => last,
}
};
(segment, Some(var.parent.into()))
}
_ => last,
};
self.substs_from_path_segment(segment, generic_def, infer_args, None)
}
Expand Down Expand Up @@ -1660,7 +1664,7 @@ impl ValueTyDefId {
Self::FunctionId(id) => Some(id.into()),
Self::StructId(id) => Some(id.into()),
Self::UnionId(id) => Some(id.into()),
Self::EnumVariantId(var) => Some(var.parent.into()),
Self::EnumVariantId(var) => Some(var.into()),
Self::ConstId(id) => Some(id.into()),
Self::StaticId(_) => None,
}
Expand Down

0 comments on commit 974caaf

Please sign in to comment.