Skip to content

Commit

Permalink
Auto merge of #125076 - compiler-errors:alias-term, r=lcnr
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed May 13, 2024
2 parents ab14f94 + fa84018 commit 3458211
Show file tree
Hide file tree
Showing 73 changed files with 695 additions and 458 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
clauses.iter().any(|pred| {
match pred.kind().skip_binder() {
ty::ClauseKind::Trait(data) if data.self_ty() == ty => {}
ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
ty::ClauseKind::Projection(data)
if data.projection_term.self_ty() == ty => {}
_ => return false,
}
tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyParam(region))
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/constrained_generic_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down
19 changes: 10 additions & 9 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)`.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
);
}
Expand All @@ -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());
Expand Down
24 changes: 8 additions & 16 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 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}");
let term = pred.term;
let obligation = format!("{projection_term} = {term}");
let quiet = format!("{quiet_projection_term} = {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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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(..) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/variance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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..] {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.misc(span),
self.param_env,
ty::ProjectionPredicate {
projection_ty: ty::AliasTy::new(
projection_term: ty::AliasTerm::new(
self.tcx,
fn_once_output_def_id,
[arg_ty.into(), fn_sig.inputs()[0].into(), const_param],
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// many viable options, so pick the most restrictive.
let trait_def_id = match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
Some(data.projection_ty.trait_def_id(self.tcx))
Some(data.projection_term.trait_def_id(self.tcx))
}
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => Some(data.def_id()),
_ => None,
Expand Down Expand Up @@ -476,7 +476,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => return None,
}

let arg_param_ty = projection.skip_binder().projection_ty.args.type_at(1);
let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1);
let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty);
debug!(?arg_param_ty);

Expand Down Expand Up @@ -931,7 +931,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};

// Check that this is a projection from the `Future` trait.
let trait_def_id = predicate.projection_ty.trait_def_id(self.tcx);
let trait_def_id = predicate.projection_term.trait_def_id(self.tcx);
let future_trait = self.tcx.require_lang_item(LangItem::Future, Some(cause_span));
if trait_def_id != future_trait {
debug!("deduce_future_output_from_projection: not a future");
Expand All @@ -941,11 +941,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// The `Future` trait has only one associated item, `Output`,
// so check that this is what we see.
let output_assoc_item = self.tcx.associated_item_def_ids(future_trait)[0];
if output_assoc_item != predicate.projection_ty.def_id {
if output_assoc_item != predicate.projection_term.def_id {
span_bug!(
cause_span,
"projecting associated item `{:?}` from future, which is not Output `{:?}`",
predicate.projection_ty.def_id,
predicate.projection_term.def_id,
output_assoc_item,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::ClauseKind::Trait(pred) => {
(pred.trait_ref.args.to_vec(), Some(pred.self_ty().into()))
}
ty::ClauseKind::Projection(pred) => (pred.projection_ty.args.to_vec(), None),
ty::ClauseKind::Projection(pred) => (pred.projection_term.args.to_vec(), None),
ty::ClauseKind::ConstArgHasType(arg, ty) => (vec![ty.into(), arg.into()], None),
ty::ClauseKind::ConstEvaluatable(e) => (vec![e.into()], None),
_ => return false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.type_matches_expected_vid(expected_vid, data.self_ty())
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
self.type_matches_expected_vid(expected_vid, data.projection_ty.self_ty())
self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty())
}
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
| ty::PredicateKind::Subtype(..)
Expand Down
23 changes: 8 additions & 15 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ use std::borrow::Cow;
use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope};
use super::{CandidateSource, MethodError, NoMatchData};
use rustc_hir::intravisit::Visitor;
use std::iter;

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
Expand Down Expand Up @@ -173,7 +172,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::AliasKind::Opaque, _) => {
ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::Opaque, _) => {
for unsatisfied in unsatisfied_predicates.iter() {
if is_iterator_predicate(unsatisfied.0, self.tcx) {
return true;
Expand Down Expand Up @@ -788,26 +787,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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 args_with_infer_self = tcx.mk_args_from_iter(
iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into())
.chain(projection_ty.args.iter().skip(1)),
);

let quiet_projection_ty =
ty::AliasTy::new(tcx, projection_ty.def_id, args_with_infer_self);
let projection_term = pred.skip_binder().projection_term;
let quiet_projection_term =
projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));

let term = pred.skip_binder().term;

let obligation = format!("{projection_ty} = {term}");
let obligation = format!("{projection_term} = {term}");
let quiet = with_forced_trimmed_paths!(format!(
"{} = {}",
quiet_projection_ty, term
quiet_projection_term, 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;
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,20 @@ impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
}

impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
fn to_trace(
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
a: Self,
b: Self,
) -> TypeTrace<'tcx> {
TypeTrace {
cause: cause.clone(),
values: Aliases(ExpectedFound::new(a_is_expected, a.into(), b.into())),
}
}
}

impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> {
fn to_trace(
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
Expand Down
Loading

0 comments on commit 3458211

Please sign in to comment.