Skip to content

Commit 5456eec

Browse files
Clean up substs building
1 parent 0828444 commit 5456eec

File tree

1 file changed

+50
-53
lines changed

1 file changed

+50
-53
lines changed

Diff for: compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+50-53
Original file line numberDiff line numberDiff line change
@@ -1876,14 +1876,17 @@ pub(super) fn check_type_bounds<'tcx>(
18761876
impl_ty: ty::AssocItem,
18771877
impl_trait_ref: ty::TraitRef<'tcx>,
18781878
) -> Result<(), ErrorGuaranteed> {
1879+
let param_env = tcx.param_env(impl_ty.def_id);
1880+
let container_id = impl_ty.container_id(tcx);
18791881
// Given
18801882
//
18811883
// impl<A, B> Foo<u32> for (A, B) {
1882-
// type Bar<C> =...
1884+
// type Bar<C> = Wrapper<A, B, C>
18831885
// }
18841886
//
18851887
// - `impl_trait_ref` would be `<(A, B) as Foo<u32>>`
1886-
// - `impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0)
1888+
// - `normalize_impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0)
1889+
// - `normalize_impl_ty` would be `Wrapper<A, B, ^0.0>`
18871890
// - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from
18881891
// the *trait* with the generic associated type parameters (as bound vars).
18891892
//
@@ -1912,56 +1915,46 @@ pub(super) fn check_type_bounds<'tcx>(
19121915
// Member<C: Eq> = .... That type would fail a well-formedness check that we ought to be doing
19131916
// elsewhere, which would check that any <T as Family>::Member<X> meets the bounds declared in
19141917
// the trait (notably, that X: Eq and T: Family).
1915-
let defs: &ty::Generics = tcx.generics_of(impl_ty.def_id);
1916-
let mut substs = smallvec::SmallVec::with_capacity(defs.count());
1917-
if let Some(def_id) = defs.parent {
1918-
let parent_defs = tcx.generics_of(def_id);
1919-
InternalSubsts::fill_item(&mut substs, tcx, parent_defs, &mut |param, _| {
1920-
tcx.mk_param_from_def(param)
1921-
});
1922-
}
19231918
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
1924-
smallvec::SmallVec::with_capacity(defs.count());
1925-
InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param.kind {
1926-
GenericParamDefKind::Type { .. } => {
1927-
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
1928-
let bound_var = ty::BoundVariableKind::Ty(kind);
1929-
bound_vars.push(bound_var);
1930-
tcx.mk_bound(
1931-
ty::INNERMOST,
1932-
ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
1933-
)
1934-
.into()
1935-
}
1936-
GenericParamDefKind::Lifetime => {
1937-
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
1938-
let bound_var = ty::BoundVariableKind::Region(kind);
1939-
bound_vars.push(bound_var);
1940-
tcx.mk_re_late_bound(
1941-
ty::INNERMOST,
1942-
ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
1943-
)
1944-
.into()
1945-
}
1946-
GenericParamDefKind::Const { .. } => {
1947-
let bound_var = ty::BoundVariableKind::Const;
1948-
bound_vars.push(bound_var);
1949-
tcx.mk_const(
1950-
ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1)),
1951-
tcx.type_of(param.def_id).subst_identity(),
1952-
)
1953-
.into()
1954-
}
1955-
});
1956-
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
1957-
let impl_ty_substs = tcx.mk_substs(&substs);
1958-
let container_id = impl_ty.container_id(tcx);
1959-
1960-
let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
1961-
let impl_ty_value = tcx.type_of(impl_ty.def_id).subst(tcx, impl_ty_substs);
1962-
1963-
let param_env = tcx.param_env(impl_ty.def_id);
1964-
1919+
smallvec::SmallVec::with_capacity(tcx.generics_of(impl_ty.def_id).params.len());
1920+
// Extend the impl's identity substs with late-bound GAT vars
1921+
let normalize_impl_ty_substs = ty::InternalSubsts::identity_for_item(tcx, container_id)
1922+
.extend_to(tcx, impl_ty.def_id, |param, _| match param.kind {
1923+
GenericParamDefKind::Type { .. } => {
1924+
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
1925+
let bound_var = ty::BoundVariableKind::Ty(kind);
1926+
bound_vars.push(bound_var);
1927+
tcx.mk_bound(
1928+
ty::INNERMOST,
1929+
ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
1930+
)
1931+
.into()
1932+
}
1933+
GenericParamDefKind::Lifetime => {
1934+
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
1935+
let bound_var = ty::BoundVariableKind::Region(kind);
1936+
bound_vars.push(bound_var);
1937+
tcx.mk_re_late_bound(
1938+
ty::INNERMOST,
1939+
ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
1940+
)
1941+
.into()
1942+
}
1943+
GenericParamDefKind::Const { .. } => {
1944+
let bound_var = ty::BoundVariableKind::Const;
1945+
bound_vars.push(bound_var);
1946+
tcx.mk_const(
1947+
ty::ConstKind::Bound(
1948+
ty::INNERMOST,
1949+
ty::BoundVar::from_usize(bound_vars.len() - 1),
1950+
),
1951+
tcx.type_of(param.def_id)
1952+
.no_bound_vars()
1953+
.expect("const parameter types cannot be generic"),
1954+
)
1955+
.into()
1956+
}
1957+
});
19651958
// When checking something like
19661959
//
19671960
// trait X { type Y: PartialEq<<Self as X>::Y> }
@@ -1971,9 +1964,13 @@ pub(super) fn check_type_bounds<'tcx>(
19711964
// we want <T as X>::Y to normalize to S. This is valid because we are
19721965
// checking the default value specifically here. Add this equality to the
19731966
// ParamEnv for normalization specifically.
1967+
let normalize_impl_ty = tcx.type_of(impl_ty.def_id).subst(tcx, normalize_impl_ty_substs);
1968+
let rebased_substs =
1969+
normalize_impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
1970+
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
19741971
let normalize_param_env = {
19751972
let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>();
1976-
match impl_ty_value.kind() {
1973+
match normalize_impl_ty.kind() {
19771974
ty::Alias(ty::Projection, proj)
19781975
if proj.def_id == trait_ty.def_id && proj.substs == rebased_substs =>
19791976
{
@@ -1987,7 +1984,7 @@ pub(super) fn check_type_bounds<'tcx>(
19871984
ty::Binder::bind_with_vars(
19881985
ty::ProjectionPredicate {
19891986
projection_ty: tcx.mk_alias_ty(trait_ty.def_id, rebased_substs),
1990-
term: impl_ty_value.into(),
1987+
term: normalize_impl_ty.into(),
19911988
},
19921989
bound_vars,
19931990
)

0 commit comments

Comments
 (0)