Auto merge of #125076 - compiler-errors:alias-term, r=lcnr

Split out `ty::AliasTerm` from `ty::AliasTy`

Splitting out `AliasTerm` (for use in project and normalizes goals) and `AliasTy` (for use in `ty::Alias`)

r? lcnr
This commit is contained in:
bors 2024-05-13 22:20:43 +00:00
commit 34582118af
73 changed files with 695 additions and 458 deletions

View file

@ -2206,7 +2206,7 @@ fn param_env_with_gat_bounds<'tcx>(
_ => predicates.push(
ty::Binder::bind_with_vars(
ty::ProjectionPredicate {
projection_ty: ty::AliasTy::new(tcx, trait_ty.def_id, rebased_args),
projection_term: ty::AliasTerm::new(tcx, trait_ty.def_id, rebased_args),
term: normalize_impl_ty.into(),
},
bound_vars,

View file

@ -344,9 +344,10 @@ fn bounds_from_generic_predicates<'tcx>(
let mut projections_str = vec![];
for projection in &projections {
let p = projection.skip_binder();
let alias_ty = p.projection_ty;
if bound == tcx.parent(alias_ty.def_id) && alias_ty.self_ty() == ty {
let name = tcx.item_name(alias_ty.def_id);
if bound == tcx.parent(p.projection_term.def_id)
&& p.projection_term.self_ty() == ty
{
let name = tcx.item_name(p.projection_term.def_id);
projections_str.push(format!("{} = {}", name, p.term));
}
}

View file

@ -40,7 +40,7 @@ fn associated_type_bounds<'tcx>(
let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| {
match pred.kind().skip_binder() {
ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty,
ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty,
ty::ClauseKind::Projection(proj) => proj.projection_term.self_ty() == item_ty,
ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty,
_ => false,
}

View file

@ -446,7 +446,9 @@ pub(super) fn explicit_predicates_of<'tcx>(
.copied()
.filter(|(pred, _)| match pred.kind().skip_binder() {
ty::ClauseKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()),
ty::ClauseKind::Projection(proj) => !is_assoc_item_ty(proj.projection_ty.self_ty()),
ty::ClauseKind::Projection(proj) => {
!is_assoc_item_ty(proj.projection_term.self_ty())
}
ty::ClauseKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0),
_ => true,
})

View file

@ -198,7 +198,7 @@ pub fn setup_constraining_predicates<'tcx>(
// Special case: watch out for some kind of sneaky attempt
// to project out an associated type defined by this very
// trait.
let unbound_trait_ref = projection.projection_ty.trait_ref(tcx);
let unbound_trait_ref = projection.projection_term.trait_ref(tcx);
if Some(unbound_trait_ref) == impl_trait_ref {
continue;
}
@ -208,7 +208,7 @@ pub fn setup_constraining_predicates<'tcx>(
// `<<T as Bar>::Baz as Iterator>::Output = <U as Iterator>::Output`
// Then the projection only applies if `T` is known, but it still
// does not determine `U`.
let inputs = parameters_for(tcx, projection.projection_ty, true);
let inputs = parameters_for(tcx, projection.projection_term, true);
let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(p));
if !relies_only_on_inputs {
continue;

View file

@ -327,7 +327,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
})
.or_insert(binding.span);
let projection_ty = if let ty::AssocKind::Fn = assoc_kind {
let projection_term = if let ty::AssocKind::Fn = assoc_kind {
let mut emitted_bad_param_err = None;
// If we have an method return type bound, then we need to instantiate
// the method's early bound params with suitable late-bound params.
@ -381,7 +381,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind()
&& tcx.is_impl_trait_in_trait(alias_ty.def_id)
{
alias_ty
alias_ty.into()
} else {
return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
span: binding.span,
@ -422,10 +422,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
);
debug!(?alias_args);
// Note that we're indeed also using `AliasTy` (alias *type*) for associated
// *constants* to represent *const projections*. Alias *term* would be a more
// appropriate name but alas.
ty::AliasTy::new(tcx, assoc_item.def_id, alias_args)
ty::AliasTerm::new(tcx, assoc_item.def_id, alias_args)
});
// Provide the resolved type of the associated constant to `type_of(AnonConst)`.
@ -462,7 +459,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
let late_bound_in_projection_ty =
tcx.collect_constrained_late_bound_regions(projection_ty);
tcx.collect_constrained_late_bound_regions(projection_term);
let late_bound_in_term =
tcx.collect_referenced_late_bound_regions(trait_ref.rebind(term));
debug!(?late_bound_in_projection_ty);
@ -491,8 +488,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
bounds.push_projection_bound(
tcx,
projection_ty
.map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }),
projection_term.map_bound(|projection_term| ty::ProjectionPredicate {
projection_term,
term,
}),
binding.span,
);
}
@ -502,6 +501,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into
// a trait predicate, since we only want to add predicates for the `Self` type.
if !only_self_bounds.0 {
let projection_ty = projection_term
.map_bound(|projection_term| projection_term.expect_ty(self.tcx()));
// Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
// parameter to have a skipped binder.
let param_ty = Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());

View file

@ -626,25 +626,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let bound_predicate = pred.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
let pred = bound_predicate.rebind(pred);
// `<Foo as Iterator>::Item = String`.
let projection_ty = pred.skip_binder().projection_ty;
let projection_term = pred.projection_term;
let quiet_projection_term =
projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
let args_with_infer_self = tcx.mk_args_from_iter(
std::iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into())
.chain(projection_ty.args.iter().skip(1)),
);
let term = pred.term;
let obligation = format!("{projection_term} = {term}");
let quiet = format!("{quiet_projection_term} = {term}");
let quiet_projection_ty =
ty::AliasTy::new(tcx, projection_ty.def_id, args_with_infer_self);
let term = pred.skip_binder().term;
let obligation = format!("{projection_ty} = {term}");
let quiet = format!("{quiet_projection_ty} = {term}");
bound_span_label(projection_ty.self_ty(), &obligation, &quiet);
Some((obligation, projection_ty.self_ty()))
bound_span_label(projection_term.self_ty(), &obligation, &quiet);
Some((obligation, projection_term.self_ty()))
}
ty::PredicateKind::Clause(ty::ClauseKind::Trait(poly_trait_ref)) => {
let p = poly_trait_ref.trait_ref;

View file

@ -281,11 +281,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let existential_projections = projection_bounds.iter().map(|(bound, _)| {
bound.map_bound(|mut b| {
assert_eq!(b.projection_ty.self_ty(), dummy_self);
assert_eq!(b.projection_term.self_ty(), dummy_self);
// Like for trait refs, verify that `dummy_self` did not leak inside default type
// parameters.
let references_self = b.projection_ty.args.iter().skip(1).any(|arg| {
let references_self = b.projection_term.args.iter().skip(1).any(|arg| {
if arg.walk().any(|arg| arg == dummy_self.into()) {
return true;
}
@ -295,7 +295,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let guar = tcx
.dcx()
.span_delayed_bug(span, "trait object projection bounds reference `Self`");
b.projection_ty = replace_dummy_self_with_error(tcx, b.projection_ty, guar);
b.projection_term = replace_dummy_self_with_error(tcx, b.projection_term, guar);
}
ty::ExistentialProjection::erase_self_ty(tcx, b)

View file

@ -258,23 +258,20 @@ fn unconstrained_parent_impl_args<'tcx>(
// unconstrained parameters.
for (clause, _) in impl_generic_predicates.predicates.iter() {
if let ty::ClauseKind::Projection(proj) = clause.kind().skip_binder() {
let projection_ty = proj.projection_ty;
let projected_ty = proj.term;
let unbound_trait_ref = projection_ty.trait_ref(tcx);
let unbound_trait_ref = proj.projection_term.trait_ref(tcx);
if Some(unbound_trait_ref) == impl_trait_ref {
continue;
}
unconstrained_parameters.extend(cgp::parameters_for(tcx, projection_ty, true));
unconstrained_parameters.extend(cgp::parameters_for(tcx, proj.projection_term, true));
for param in cgp::parameters_for(tcx, projected_ty, false) {
for param in cgp::parameters_for(tcx, proj.term, false) {
if !unconstrained_parameters.contains(&param) {
constrained_params.insert(param.0);
}
}
unconstrained_parameters.extend(cgp::parameters_for(tcx, projected_ty, true));
unconstrained_parameters.extend(cgp::parameters_for(tcx, proj.term, true));
}
}
@ -495,11 +492,11 @@ fn check_specialization_on<'tcx>(
.emit())
}
}
ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => Err(tcx
ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_term, term }) => Err(tcx
.dcx()
.struct_span_err(
span,
format!("cannot specialize on associated type `{projection_ty} == {term}`",),
format!("cannot specialize on associated type `{projection_term} == {term}`",),
)
.emit()),
ty::ClauseKind::ConstArgHasType(..) => {

View file

@ -167,7 +167,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
}
}
ty::ClauseKind::Projection(ty::ProjectionPredicate {
projection_ty: ty::AliasTy { args, .. },
projection_term: ty::AliasTerm { args, .. },
term,
}) => {
for arg in &args[1..] {