ty::Alias refactor: fixup all the compiler code

This commit is contained in:
Waffle Lapkin
2026-03-05 14:07:17 +01:00
parent cf96c5fa87
commit 0f767084b8
105 changed files with 819 additions and 557 deletions
@@ -219,11 +219,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindOpaqueRegion<'_, 'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
// If we find an opaque in a local ty, then for each of its captured regions,
// try to find a path between that captured regions and our borrow region...
if let ty::Alias(ty::Opaque, opaque) = *ty.kind()
if let ty::Alias(opaque @ ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind()
&& let hir::OpaqueTyOrigin::FnReturn { parent, in_trait_or_impl: None } =
self.tcx.opaque_ty_origin(opaque.def_id)
self.tcx.opaque_ty_origin(def_id)
{
let variances = self.tcx.variances_of(opaque.def_id);
let variances = self.tcx.variances_of(def_id);
for (idx, (arg, variance)) in std::iter::zip(opaque.args, variances).enumerate() {
// Skip uncaptured args.
if *variance == ty::Bivariant {
@@ -252,7 +252,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
&& call_def_id == parent
&& let Locations::Single(location) = constraint.locations
{
return ControlFlow::Break((opaque.def_id, idx, location));
return ControlFlow::Break((def_id, idx, location));
}
}
}
@@ -276,11 +276,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for CheckExplicitRegionMentionAndCollectGen
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
match *ty.kind() {
ty::Alias(ty::Opaque, opaque) => {
if self.seen_opaques.insert(opaque.def_id) {
ty::Alias(opaque @ ty::AliasTy { kind: ty::Opaque { def_id }, .. }) => {
if self.seen_opaques.insert(def_id) {
for (bound, _) in self
.tcx
.explicit_item_bounds(opaque.def_id)
.explicit_item_bounds(def_id)
.iter_instantiated_copied(self.tcx, opaque.args)
{
bound.visit_with(self)?;
@@ -594,7 +594,7 @@ fn report_fnmut_error(
let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *output_ty.kind() {
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *output_ty.kind() {
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity()
};
+2 -2
View File
@@ -1899,7 +1899,7 @@ fn check_movable_place(&mut self, location: Location, place: Place<'tcx>) {
| ty::Never
| ty::Tuple(_)
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Infer(_)
@@ -1941,7 +1941,7 @@ fn check_movable_place(&mut self, location: Location, place: Place<'tcx>) {
| ty::CoroutineWitness(..)
| ty::Never
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Infer(_)
@@ -176,8 +176,8 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
| ty::CoroutineClosure(def_id, args)
| ty::Coroutine(def_id, args) => self.visit_closure_args(def_id, args),
ty::Alias(kind, ty::AliasTy { def_id, args, .. })
if let Some(variances) = self.cx().opt_alias_variances(kind, def_id) =>
ty::Alias(ty::AliasTy { kind, args, .. })
if let Some(variances) = self.cx().opt_alias_variances(kind, kind.def_id()) =>
{
// Skip lifetime parameters that are not captured, since they do
// not need member constraints registered for them; we'll erase
@@ -367,9 +367,10 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
// writeback.
if !rcx.infcx.tcx.use_typing_mode_borrowck() {
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.skip_binder().kind()
&& alias_ty.def_id == opaque_type_key.def_id.to_def_id()
&& alias_ty.args == opaque_type_key.args
if let &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
hidden_type.ty.skip_binder().kind()
&& def_id == opaque_type_key.def_id.to_def_id()
&& args == opaque_type_key.args
{
continue;
}
@@ -499,8 +500,8 @@ fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, RegionVid> {
Ty::new_coroutine(tcx, def_id, self.fold_closure_args(def_id, args)?)
}
ty::Alias(kind, ty::AliasTy { def_id, args, .. })
if let Some(variances) = tcx.opt_alias_variances(kind, def_id) =>
ty::Alias(ty::AliasTy { kind, args, .. })
if let Some(variances) = tcx.opt_alias_variances(kind, kind.def_id()) =>
{
let args = tcx.mk_args_from_iter(std::iter::zip(variances, args.iter()).map(
|(&v, s)| {
@@ -511,7 +512,7 @@ fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, RegionVid> {
}
},
))?;
ty::AliasTy::new_from_args(tcx, def_id, args).to_ty(tcx)
ty::AliasTy::new_from_args(tcx, kind, args).to_ty(tcx)
}
_ => ty.try_super_fold_with(self)?,
@@ -540,9 +541,10 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
for &(key, hidden_type) in opaque_types {
let Some(expected) = hidden_types.get(&key.def_id) else {
if !tcx.use_typing_mode_borrowck() {
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
&& alias_ty.def_id == key.def_id.to_def_id()
&& alias_ty.args == key.args
if let &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
hidden_type.ty.kind()
&& def_id == key.def_id.to_def_id()
&& args == key.args
{
continue;
} else {
@@ -450,7 +450,8 @@ fn relate_type_and_user_type(
// Necessary for non-trivial patterns whose user-type annotation is an opaque type,
// e.g. `let (_a,): Tait = whatever`, see #105897
if !self.infcx.next_trait_solver()
&& let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind()
&& let ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) =
curr_projected_ty.ty.kind()
{
// There is nothing that we can compare here if we go through an opaque type.
// We're always in its defining scope as we can otherwise not project through
@@ -150,8 +150,12 @@ fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()>
};
let (a, b) = match (a.kind(), b.kind()) {
(&ty::Alias(ty::Opaque, ..), _) => (a, enable_subtyping(b, true)?),
(_, &ty::Alias(ty::Opaque, ..)) => (enable_subtyping(a, false)?, b),
(&ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }), _) => {
(a, enable_subtyping(b, true)?)
}
(_, &ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. })) => {
(enable_subtyping(a, false)?, b)
}
_ => unreachable!(
"expected at least one opaque type in `relate_opaques`, got {a} and {b}."
),
@@ -382,8 +386,8 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
}
(
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: a_def_id }, .. }),
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: b_def_id }, .. }),
) if a_def_id == b_def_id || infcx.next_trait_solver() => {
super_combine_tys(&infcx.infcx, self, a, b).map(|_| ()).or_else(|err| {
// This behavior is only there for the old solver, the new solver
@@ -397,8 +401,8 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
if a_def_id.is_local() { self.relate_opaques(a, b) } else { Err(err) }
})?;
}
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
(&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }), _)
| (_, &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }))
if def_id.is_local() && !self.type_checker.infcx.next_trait_solver() =>
{
self.relate_opaques(a, b)?;
@@ -53,14 +53,22 @@ fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
// Types with identity (print the module path).
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args)
| ty::FnDef(def_id, args)
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
| ty::Alias(ty::AliasTy {
kind: ty::Projection { def_id } | ty::Opaque { def_id },
args,
..
})
| ty::Closure(def_id, args)
| ty::CoroutineClosure(def_id, args)
| ty::Coroutine(def_id, args) => self.print_def_path(def_id, args),
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
ty::Alias(ty::Free, _) => bug!("type_name: unexpected free alias"),
ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"),
ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. }) => {
bug!("type_name: unexpected free alias")
}
ty::Alias(ty::AliasTy { kind: ty::Inherent { .. }, .. }) => {
bug!("type_name: unexpected inherent projection")
}
ty::CoroutineWitness(..) => bug!("type_name: unexpected `CoroutineWitness`"),
}
}
@@ -523,8 +523,8 @@ fn sanity_check_found_hidden_type<'tcx>(
// Nothing was actually constrained.
return Ok(());
}
if let ty::Alias(ty::Opaque, alias) = ty.ty.kind() {
if alias.def_id == key.def_id.to_def_id() && alias.args == key.args {
if let &ty::Alias(alias @ ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = ty.ty.kind() {
if def_id == key.def_id.to_def_id() && alias.args == key.args {
// Nothing was actually constrained, this is an opaque usage that was
// only discovered to be opaque after inference vars resolved.
return Ok(());
@@ -2150,7 +2150,7 @@ struct OpaqueTypeCollector {
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match *t.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: def }, .. }) => {
self.opaques.push(def);
}
ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
@@ -2183,10 +2183,10 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
let mut label_match = |ty: Ty<'_>, span| {
for arg in ty.walk() {
if let ty::GenericArgKind::Type(ty) = arg.kind()
&& let ty::Alias(
ty::Opaque,
ty::AliasTy { def_id: captured_def_id, .. },
) = *ty.kind()
&& let ty::Alias(ty::AliasTy {
kind: ty::Opaque { def_id: captured_def_id },
..
}) = *ty.kind()
&& captured_def_id == opaque_def_id.to_def_id()
{
err.span_label(
@@ -820,10 +820,10 @@ fn cx(&self) -> TyCtxt<'tcx> {
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Alias(ty::Projection, proj) = ty.kind()
&& self.cx().is_impl_trait_in_trait(proj.def_id)
if let &ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. }) = ty.kind()
&& self.cx().is_impl_trait_in_trait(def_id)
{
if let Some((ty, _)) = self.types.get(&proj.def_id) {
if let Some((ty, _)) = self.types.get(&def_id) {
return *ty;
}
//FIXME(RPITIT): Deny nested RPITIT in args too
@@ -832,11 +832,11 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
}
// Replace with infer var
let infer_ty = self.ocx.infcx.next_ty_var(self.span);
self.types.insert(proj.def_id, (infer_ty, proj.args));
self.types.insert(def_id, (infer_ty, proj.args));
// Recurse into bounds
for (pred, pred_span) in self
.cx()
.explicit_item_bounds(proj.def_id)
.explicit_item_bounds(def_id)
.iter_instantiated_copied(self.cx(), proj.args)
{
let pred = pred.fold_with(self);
@@ -851,7 +851,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
ObligationCause::new(
self.span,
self.body_id,
ObligationCauseCode::WhereClause(proj.def_id, pred_span),
ObligationCauseCode::WhereClause(def_id, pred_span),
),
self.param_env,
pred,
@@ -922,8 +922,12 @@ fn try_fold_region(
} else {
let guar = match region.opt_param_def_id(self.tcx, self.impl_m_def_id) {
Some(def_id) => {
let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
self.tcx.def_span(opaque_ty.def_id)
let return_span = if let &ty::Alias(ty::AliasTy {
kind: ty::Opaque { def_id: opaque_ty_def_id },
..
}) = self.ty.kind()
{
self.tcx.def_span(opaque_ty_def_id)
} else {
self.return_span
};
@@ -2703,8 +2707,8 @@ fn param_env_with_gat_bounds<'tcx>(
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
match normalize_impl_ty.kind() {
ty::Alias(ty::Projection, proj)
if proj.def_id == trait_ty.def_id && proj.args == rebased_args =>
&ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. })
if def_id == trait_ty.def_id && proj.args == rebased_args =>
{
// Don't include this predicate if the projected type is
// exactly the same as the projection. This can occur in
@@ -2746,7 +2750,7 @@ fn try_report_async_mismatch<'tcx>(
return Ok(());
}
let ty::Alias(ty::Projection, ty::AliasTy { def_id: async_future_def_id, .. }) =
let ty::Alias(ty::AliasTy { kind: ty::Projection { def_id: async_future_def_id }, .. }) =
*tcx.fn_sig(trait_m.def_id).skip_binder().skip_binder().output().kind()
else {
bug!("expected `async fn` to return an RPITIT");
@@ -80,10 +80,14 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
for trait_projection in collector.types.into_iter().rev() {
let impl_opaque_args = trait_projection.args.rebase_onto(tcx, trait_m.def_id, impl_m_args);
let hidden_ty = hidden_tys[&trait_projection.def_id].instantiate(tcx, impl_opaque_args);
let hidden_ty =
hidden_tys[&trait_projection.kind.def_id()].instantiate(tcx, impl_opaque_args);
// If the hidden type is not an opaque, then we have "refined" the trait signature.
let ty::Alias(ty::Opaque, impl_opaque) = *hidden_ty.kind() else {
let ty::Alias(
impl_opaque @ ty::AliasTy { kind: ty::Opaque { def_id: impl_opaque_def_id }, .. },
) = *hidden_ty.kind()
else {
report_mismatched_rpitit_signature(
tcx,
trait_m_sig_with_self_for_diag,
@@ -97,7 +101,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
// This opaque also needs to be from the impl method -- otherwise,
// it's a refinement to a TAIT.
if !tcx.hir_get_if_local(impl_opaque.def_id).is_some_and(|node| {
if !tcx.hir_get_if_local(impl_opaque_def_id).is_some_and(|node| {
matches!(
node.expect_opaque_ty().origin,
hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. }
@@ -116,11 +120,12 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
}
trait_bounds.extend(
tcx.item_bounds(trait_projection.def_id).iter_instantiated(tcx, trait_projection.args),
tcx.item_bounds(trait_projection.kind.def_id())
.iter_instantiated(tcx, trait_projection.args),
);
impl_bounds.extend(elaborate(
tcx,
tcx.explicit_item_bounds(impl_opaque.def_id)
tcx.explicit_item_bounds(impl_opaque_def_id)
.iter_instantiated_copied(tcx, impl_opaque.args),
));
@@ -218,7 +223,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
// is literally unrepresentable in the type system; however, we may be
// promising stronger outlives guarantees if we capture *fewer* regions.
for (trait_projection, impl_opaque) in pairs {
let impl_variances = tcx.variances_of(impl_opaque.def_id);
let impl_variances = tcx.variances_of(impl_opaque.kind.def_id());
let impl_captures: FxIndexSet<_> = impl_opaque
.args
.iter()
@@ -227,7 +232,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
.map(|(arg, _)| arg)
.collect();
let trait_variances = tcx.variances_of(trait_projection.def_id);
let trait_variances = tcx.variances_of(trait_projection.kind.def_id());
let mut trait_captures = FxIndexSet::default();
for (arg, variance) in trait_projection.args.iter().zip_eq(trait_variances) {
if *variance != ty::Invariant {
@@ -239,7 +244,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
if !trait_captures.iter().all(|arg| impl_captures.contains(arg)) {
report_mismatched_rpitit_captures(
tcx,
impl_opaque.def_id.expect_local(),
impl_opaque.kind.def_id().expect_local(),
trait_captures,
is_internal,
);
@@ -254,13 +259,13 @@ struct ImplTraitInTraitCollector<'tcx> {
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) {
if let ty::Alias(ty::Projection, proj) = *ty.kind()
&& self.tcx.is_impl_trait_in_trait(proj.def_id)
if let ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. }) = *ty.kind()
&& self.tcx.is_impl_trait_in_trait(def_id)
{
if self.types.insert(proj) {
for (pred, _) in self
.tcx
.explicit_item_bounds(proj.def_id)
.explicit_item_bounds(def_id)
.iter_instantiated_copied(self.tcx, proj.args)
{
pred.visit_with(self);
@@ -303,14 +308,17 @@ fn report_mismatched_rpitit_signature<'tcx>(
let mut return_ty = trait_m_sig.output().fold_with(&mut super::RemapLateParam { tcx, mapping });
if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() {
let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else {
let &ty::Alias(
future_ty @ ty::AliasTy { kind: ty::Projection { def_id: future_ty_def_id }, .. },
) = return_ty.kind()
else {
span_bug!(
tcx.def_span(trait_m_def_id),
"expected return type of async fn in trait to be a AFIT projection"
);
};
let Some(future_output_ty) = tcx
.explicit_item_bounds(future_ty.def_id)
.explicit_item_bounds(future_ty_def_id)
.iter_instantiated_copied(tcx, future_ty.args)
.find_map(|(clause, _)| match clause.kind().no_bound_vars()? {
ty::ClauseKind::Projection(proj) => proj.term.as_type(),
+2 -2
View File
@@ -485,9 +485,9 @@ fn fn_sig_suggestion<'tcx>(
let mut output = sig.output();
let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
output = if let ty::Alias(_, alias_ty) = *output.kind()
output = if let ty::Alias(alias_ty) = *output.kind()
&& let Some(output) = tcx
.explicit_item_self_bounds(alias_ty.def_id)
.explicit_item_self_bounds(alias_ty.kind.def_id())
.iter_instantiated_copied(tcx, alias_ty.args)
.find_map(|(bound, _)| {
bound.as_projection_clause()?.no_bound_vars()?.term.as_type()
@@ -773,7 +773,9 @@ fn visit<T: TypeFoldable<TyCtxt<'tcx>>>(
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
&ty::Alias(p @ ty::AliasTy { kind: ty::Projection { def_id }, .. })
if def_id == self.gat =>
{
for (idx, arg) in p.args.iter().enumerate() {
match arg.kind() {
GenericArgKind::Lifetime(lt) if !lt.is_bound() => {
@@ -2250,7 +2252,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsProbablyCyclical<'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<(), ()> {
let def_id = match ty.kind() {
ty::Adt(adt_def, _) => Some(adt_def.did()),
ty::Alias(ty::Free, alias_ty) => Some(alias_ty.def_id),
&ty::Alias(ty::AliasTy { kind: ty::Free { def_id }, .. }) => Some(def_id),
_ => None,
};
if let Some(def_id) = def_id {
@@ -195,7 +195,11 @@ fn check_item(&mut self, id: hir::ItemId) -> Result<(), ErrorGuaranteed> {
| ty::FnPtr(..)
| ty::Tuple(..)
| ty::UnsafeBinder(_) => self.check_primitive_impl(id, self_ty),
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) | ty::Param(_) => {
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Opaque { .. },
..
})
| ty::Param(_) => {
Err(self.tcx.dcx().emit_err(errors::InherentNominal { span: item_span }))
}
ty::FnDef(..)
@@ -203,7 +207,7 @@ fn check_item(&mut self, id: hir::ItemId) -> Result<(), ErrorGuaranteed> {
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Alias(ty::Free, _)
| ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. })
| ty::Bound(..)
| ty::Placeholder(_)
| ty::Infer(_) => {
@@ -179,20 +179,20 @@ enum NonlocalImpl {
NonlocalImpl::DisallowOther,
),
ty::Alias(kind, _) => {
ty::Alias(ty::AliasTy { kind, .. }) => {
let problematic_kind = match kind {
// trait Id { type This: ?Sized; }
// impl<T: ?Sized> Id for T {
// type This = T;
// }
// impl<T: ?Sized> AutoTrait for <T as Id>::This {}
ty::Projection => "associated type",
ty::Projection { .. } => "associated type",
// type Foo = (impl Sized, bool)
// impl AutoTrait for Foo {}
ty::Free => "type alias",
ty::Free { .. } => "type alias",
// type Opaque = impl Trait;
// impl AutoTrait for Opaque {}
ty::Opaque => "opaque type",
ty::Opaque { .. } => "opaque type",
// ```
// struct S<T>(T);
// impl<T: ?Sized> S<T> {
@@ -201,7 +201,7 @@ enum NonlocalImpl {
// impl<T: ?Sized> AutoTrait for S<T>::This {}
// ```
// FIXME(inherent_associated_types): The example code above currently leads to a cycle
ty::Inherent => "associated type",
ty::Inherent { .. } => "associated type",
};
(LocalImpl::Disallow { problematic_kind }, NonlocalImpl::DisallowOther)
}
@@ -436,7 +436,7 @@ fn emit_orphan_check_error<'tcx>(
});
}
}
ty::Alias(ty::Opaque, ..) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) => {
diag.subdiagnostic(errors::OnlyCurrentTraitsOpaque { span });
}
ty::RawPtr(ptr_ty, mutbl) => {
@@ -143,9 +143,12 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
};
let gat_vars = loop {
if let ty::Alias(ty::Projection, alias_ty) = *clause_ty.kind() {
if let ty::Alias(
alias_ty @ ty::AliasTy { kind: ty::Projection { def_id: alias_ty_def_id }, .. },
) = *clause_ty.kind()
{
if alias_ty.trait_ref(tcx) == item_trait_ref
&& alias_ty.def_id == assoc_item_def_id.to_def_id()
&& alias_ty_def_id == assoc_item_def_id.to_def_id()
{
// We have found the GAT in question...
// Return the vars, since we may need to remap them.
@@ -546,12 +549,17 @@ fn cx(&self) -> TyCtxt<'tcx> {
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Alias(ty::Projection, projection_ty) = ty.kind()
if let &ty::Alias(
projection_ty @ ty::AliasTy {
kind: ty::Projection { def_id: projection_ty_def_id },
..
},
) = ty.kind()
&& let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
self.tcx.opt_rpitit_info(projection_ty.def_id)
self.tcx.opt_rpitit_info(projection_ty_def_id)
&& fn_def_id == self.fn_def_id
{
self.tcx.type_of(projection_ty.def_id).instantiate(self.tcx, projection_ty.args)
self.tcx.type_of(projection_ty_def_id).instantiate(self.tcx, projection_ty.args)
} else {
ty.super_fold_with(self)
}
@@ -513,11 +513,16 @@ pub(super) fn explicit_predicates_of<'tcx>(
// identity args of the trait.
// * It must be an associated type for this trait (*not* a
// supertrait).
if let ty::Alias(ty::Projection, projection) = ty.kind() {
if let &ty::Alias(
projection @ ty::AliasTy {
kind: ty::Projection { def_id: projection_def_id }, ..
},
) = ty.kind()
{
projection.args == trait_identity_args
// FIXME(return_type_notation): This check should be more robust
&& !tcx.is_impl_trait_in_trait(projection.def_id)
&& tcx.parent(projection.def_id) == def_id.to_def_id()
&& !tcx.is_impl_trait_in_trait(projection_def_id)
&& tcx.parent(projection_def_id) == def_id.to_def_id()
} else {
false
}
@@ -2407,7 +2407,10 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
ty::Param(param_ty) => {
self.arg_is_constrained[param_ty.index as usize] = true;
}
ty::Alias(ty::Projection | ty::Inherent, _) => return,
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. },
..
}) => return,
_ => (),
}
t.super_visit_with(self)
@@ -63,13 +63,16 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match *t.kind() {
// Projections are not injective in general.
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _)
if !self.include_nonconstraining =>
{
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Opaque { .. },
..
}) if !self.include_nonconstraining => {
return;
}
// All free alias types should've been expanded beforehand.
ty::Alias(ty::Free, _) if !self.include_nonconstraining => {
ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. })
if !self.include_nonconstraining =>
{
bug!("unexpected free alias type")
}
ty::Param(param) => self.parameters.push(Parameter::from(param)),
@@ -639,8 +639,7 @@ pub(super) fn lower_assoc_item_constraint(
.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());
let param_ty = Ty::new_alias(tcx, projection_ty.skip_binder());
self.lower_bounds(
param_ty,
hir_bounds,
@@ -730,7 +729,7 @@ pub fn lower_ty_maybe_return_type_notation(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<
ty::Binder::bind_with_vars(trait_ref, tcx.late_bound_vars(item_segment.hir_id));
match self.lower_return_type_notation_ty(candidate, item_def_id, hir_ty.span) {
Ok(ty) => Ty::new_alias(tcx, ty::Projection, ty),
Ok(ty) => Ty::new_alias(tcx, ty),
Err(guar) => Ty::new_error(tcx, guar),
}
}
@@ -773,7 +772,7 @@ pub fn lower_ty_maybe_return_type_notation(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<
}
match self.lower_return_type_notation_ty(bound, item_def_id, hir_ty.span) {
Ok(ty) => Ty::new_alias(tcx, ty::Projection, ty),
Ok(ty) => Ty::new_alias(tcx, ty),
Err(guar) => Ty::new_error(tcx, guar),
}
}
@@ -833,8 +832,9 @@ fn lower_return_type_notation_ty(
// Next, we need to check that the return-type notation is being used on
// an RPITIT (return-position impl trait in trait) or AFIT (async fn in trait).
let output = tcx.fn_sig(item_def_id).skip_binder().output();
let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind()
&& tcx.is_impl_trait_in_trait(alias_ty.def_id)
let output = if let ty::Alias(alias_ty) = *output.skip_binder().kind()
&& let ty::AliasTy { kind: ty::Projection { def_id: projection_def_id }, .. } = alias_ty
&& tcx.is_impl_trait_in_trait(projection_def_id)
{
alias_ty
} else {
@@ -1157,8 +1157,8 @@ fn lower_path_segment(
// Type aliases defined in crates that have the
// feature `lazy_type_alias` enabled get encoded as a type alias that normalization will
// then actually instantiate the where bounds of.
let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
Ty::new_alias(tcx, ty::Free, alias_ty)
let alias_ty = ty::AliasTy::new_from_args(tcx, ty::Free { def_id: did }, args);
Ty::new_alias(tcx, alias_ty)
} else {
tcx.at(span).type_of(did).instantiate(tcx, args)
}
@@ -1412,8 +1412,12 @@ pub fn lower_type_relative_ty_path(
LowerTypeRelativePathMode::Type(permit_variants),
)? {
TypeRelativePath::AssocItem(def_id, args) => {
let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args);
let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty);
let alias_ty = ty::AliasTy::new_from_args(
tcx,
ty::AliasTyKind::new_from_def_id(tcx, def_id),
args,
);
let ty = Ty::new_alias(tcx, alias_ty);
let ty = self.check_param_uses_if_mcg(ty, span, false);
Ok((ty, tcx.def_kind(def_id), def_id))
}
@@ -157,21 +157,21 @@ fn insert_required_predicates_to_be_wf<'tcx>(
);
}
ty::Alias(ty::Free, alias) => {
ty::Alias(ty::AliasTy { kind: ty::Free { def_id }, args, .. }) => {
// This corresponds to a type like `Type<'a, T>`.
// We check inferred and explicit predicates.
debug!("Free");
check_inferred_predicates(
tcx,
alias.def_id,
alias.args,
def_id,
args,
global_inferred_outlives,
required_predicates,
);
check_explicit_predicates(
tcx,
alias.def_id,
alias.args,
def_id,
args,
required_predicates,
explicit_map,
None,
@@ -203,15 +203,15 @@ fn insert_required_predicates_to_be_wf<'tcx>(
}
}
ty::Alias(ty::Projection, alias) => {
ty::Alias(ty::AliasTy { kind: ty::Projection { def_id }, args, .. }) => {
// This corresponds to a type like `<() as Trait<'a, T>>::Type`.
// We only use the explicit predicates of the trait but
// not the ones of the associated type itself.
debug!("Projection");
check_explicit_predicates(
tcx,
tcx.parent(alias.def_id),
alias.args,
tcx.parent(def_id),
args,
required_predicates,
explicit_map,
None,
@@ -219,7 +219,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
}
// FIXME(inherent_associated_types): Use the explicit predicates from the parent impl.
ty::Alias(ty::Inherent, _) => {}
ty::Alias(ty::AliasTy { kind: ty::Inherent { .. }, .. }) => {}
_ => {}
}
@@ -273,12 +273,16 @@ fn add_constraints_from_ty(
self.add_constraints_from_args(current, def.did(), args, variance);
}
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, ref data) => {
self.add_constraints_from_invariant_args(current, data.args, variance);
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Opaque { .. },
args,
..
}) => {
self.add_constraints_from_invariant_args(current, args, variance);
}
ty::Alias(ty::Free, ref data) => {
self.add_constraints_from_args(current, data.def_id, data.args, variance);
ty::Alias(ty::AliasTy { kind: ty::Free { def_id }, args, .. }) => {
self.add_constraints_from_args(current, def_id, args, variance);
}
ty::Dynamic(data, r) => {
@@ -143,7 +143,7 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) {
#[instrument(level = "trace", skip(self), ret)]
fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
self.visit_opaque(*def_id, args);
}
_ => t.super_visit_with(self),
+4 -2
View File
@@ -246,7 +246,7 @@ fn suggest_removing_semicolon_for_coerce(
self.may_coerce(arm_ty, ret_ty)
&& prior_arm.is_none_or(|(_, ty, _)| self.may_coerce(ty, ret_ty))
// The match arms need to unify for the case of `impl Trait`.
&& !matches!(ret_ty.kind(), ty::Alias(ty::Opaque, ..))
&& !matches!(ret_ty.kind(), ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }))
}
_ => false,
};
@@ -533,7 +533,9 @@ pub(crate) fn return_position_impl_trait_from_match_expectation(
let expected_ty = expectation.to_option(self)?;
let (def_id, args) = match *expected_ty.kind() {
// FIXME: Could also check that the RPIT is not defined
ty::Alias(ty::Opaque, alias_ty) => (alias_ty.def_id.as_local()?, alias_ty.args),
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
(def_id.as_local()?, args)
}
// FIXME(-Znext-solver=no): Remove this branch once `replace_opaque_types_with_infer` is gone.
ty::Infer(ty::TyVar(_)) => self
.inner
+1 -1
View File
@@ -122,7 +122,7 @@ fn pointer_kind(
// Pointers to foreign types are thin, despite being unsized
ty::Foreign(..) => Some(PointerKind::Thin),
// We should really try to normalize here.
ty::Alias(_, pi) => Some(PointerKind::OfAlias(pi)),
ty::Alias(pi) => Some(PointerKind::OfAlias(pi)),
ty::Param(p) => Some(PointerKind::OfParam(p)),
// Insufficient type information.
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None,
+3 -3
View File
@@ -305,7 +305,7 @@ fn deduce_closure_signature(
closure_kind: hir::ClosureKind,
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
match *expected_ty.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => self
.deduce_closure_signature_from_predicates(
expected_ty,
closure_kind,
@@ -1017,14 +1017,14 @@ fn deduce_future_output_from_obligations(&self, body_def_id: LocalDefId) -> Opti
get_future_output(obligation.predicate, obligation.cause.span)
})?
}
ty::Alias(ty::Projection, _) => {
ty::Alias(ty::AliasTy { kind: ty::Projection { .. }, .. }) => {
return Some(Ty::new_error_with_message(
self.tcx,
closure_span,
"this projection should have been projected to an opaque type",
));
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => self
.tcx
.explicit_item_self_bounds(def_id)
.iter_instantiated_copied(self.tcx, args)
+1 -1
View File
@@ -2978,7 +2978,7 @@ fn ban_nonexisting_field(
err.span_label(ident.span, "unknown field");
self.point_at_param_definition(&mut err, param_ty);
}
ty::Alias(ty::Opaque, _) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) => {
self.suggest_await_on_field_access(&mut err, ident, base, base_ty.peel_refs());
}
_ => {
@@ -1058,7 +1058,9 @@ fn find_param_in_ty<'tcx>(
return true;
}
if let ty::GenericArgKind::Type(ty) = arg.kind()
&& let ty::Alias(ty::Projection | ty::Inherent, ..) = ty.kind()
&& let ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. }, ..
}) = ty.kind()
{
// This logic may seem a bit strange, but typically when
// we have a projection type in a function signature, the
@@ -1417,7 +1417,7 @@ fn label_fn_like(
}
}
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id: new_def_id, .. })
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: new_def_id }, .. })
| ty::Closure(new_def_id, _)
| ty::FnDef(new_def_id, _) => {
def_id = new_def_id;
+9 -5
View File
@@ -403,9 +403,10 @@ fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
match ty.kind() {
ty::Adt(adt_def, _) => Some(*adt_def),
// FIXME(#104767): Should we handle bound regions here?
ty::Alias(ty::Projection | ty::Inherent | ty::Free, _)
if !ty.has_escaping_bound_vars() =>
{
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Free { .. },
..
}) if !ty.has_escaping_bound_vars() => {
if self.next_trait_solver() {
self.try_structurally_resolve_type(span, ty).ty_adt_def()
} else {
@@ -423,8 +424,11 @@ fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
// WF obligations that are registered elsewhere, but they have a
// better cause code assigned to them in `add_required_obligations_for_hir`.
// This means that they should shadow obligations with worse spans.
if let ty::Alias(ty::Projection | ty::Free, ty::AliasTy { args, def_id, .. }) =
ty.kind()
if let ty::Alias(ty::AliasTy {
kind: ty::Projection { def_id } | ty::Free { def_id },
args,
..
}) = ty.kind()
{
self.add_required_obligations_for_hir(span, *def_id, args, hir_id);
}
@@ -2041,9 +2041,9 @@ fn consider_probe(
// HACK: opaque types will match anything for which their bounds hold.
// Thus we need to prevent them from trying to match the `&_` autoref
// candidates that get created for `&self` trait methods.
ty::Alias(ty::Opaque, alias_ty)
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. })
if !self.next_trait_solver()
&& self.infcx.can_define_opaque_ty(alias_ty.def_id)
&& self.infcx.can_define_opaque_ty(def_id)
&& !xform_self_ty.is_ty_var() =>
{
return ProbeResult::NoMatch;
@@ -175,7 +175,9 @@ fn predicate_bounds_generic_param<'tcx>(
}
}
}
ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::Opaque, _) => {
ty::Slice(..)
| ty::Adt(..)
| ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) => {
for unsatisfied in unsatisfied_predicates.iter() {
if is_iterator_predicate(unsatisfied.0) {
return true;
@@ -3632,7 +3634,10 @@ fn note_derefed_ty_has_method(
| ty::Float(_)
| ty::Adt(_, _)
| ty::Str
| ty::Alias(ty::Projection | ty::Inherent, _)
| ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. },
..
})
| ty::Param(_) => format!("{deref_ty}"),
// we need to test something like <&[_]>::len or <(&[u32])>::len
// and Vec::function();
+7 -6
View File
@@ -567,9 +567,10 @@ fn visit_opaque_types(&mut self) {
for (opaque_type_key, hidden_type) in opaque_types {
let hidden_type = self.resolve(hidden_type, &hidden_type.span);
let opaque_type_key = self.resolve(opaque_type_key, &hidden_type.span);
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
&& alias_ty.def_id == opaque_type_key.def_id.to_def_id()
&& alias_ty.args == opaque_type_key.args
if let &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
hidden_type.ty.kind()
&& def_id == opaque_type_key.def_id.to_def_id()
&& args == opaque_type_key.args
{
continue;
}
@@ -1049,8 +1050,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasRecursiveOpaque<'_, 'tcx> {
type Result = ControlFlow<()>;
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
if let ty::Alias(ty::Opaque, alias_ty) = *t.kind()
&& let Some(def_id) = alias_ty.def_id.as_local()
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) = *t.kind()
&& let Some(def_id) = def_id.as_local()
{
if self.def_id == def_id {
return ControlFlow::Break(());
@@ -1059,7 +1060,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
if self.seen.insert(def_id)
&& let Some(hidden_ty) = self.opaques.get(&def_id)
{
hidden_ty.ty.instantiate(self.tcx, alias_ty.args).visit_with(self)?;
hidden_ty.ty.instantiate(self.tcx, args).visit_with(self)?;
}
}
+1 -1
View File
@@ -1022,7 +1022,7 @@ pub fn opaques_with_sub_unified_hidden_type(&self, ty_vid: TyVid) -> Vec<ty::Ali
if opaque_sub_vid == ty_sub_vid {
return Some(ty::AliasTy::new_from_args(
self.tcx,
key.def_id.into(),
ty::Opaque { def_id: key.def_id.into() },
key.args,
));
}
@@ -45,7 +45,7 @@ pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
lt_op: |lt| lt,
ct_op: |ct| ct,
ty_op: |ty| match *ty.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. })
if self.can_define_opaque_ty(def_id) && !ty.has_escaping_bound_vars() =>
{
let def_span = self.tcx.def_span(def_id);
@@ -85,7 +85,9 @@ pub fn handle_opaque_type(
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, TypeError<'tcx>> {
debug_assert!(!self.next_trait_solver());
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. })
if def_id.is_local() =>
{
let def_id = def_id.expect_local();
if let ty::TypingMode::Coherence = self.typing_mode() {
// See comment on `insert_hidden_type` for why this is sufficient in coherence
@@ -134,7 +136,9 @@ pub fn handle_opaque_type(
return None;
}
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: b_def_id }, .. }) =
*b.kind()
{
// We could accept this, but there are various ways to handle this situation,
// and we don't want to make a decision on it right now. Likely this case is so
// super rare anyway, that no one encounters it in practice. It does occur
@@ -314,12 +318,13 @@ pub fn add_item_bounds_for_hidden_type(
// but we can eagerly register inference variables for them.
// FIXME(RPITIT): Don't replace RPITITs with inference vars.
// FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
ty::Alias(ty::Projection, projection_ty)
if !projection_ty.has_escaping_bound_vars()
&& !tcx.is_impl_trait_in_trait(projection_ty.def_id)
&& !self.next_trait_solver() =>
ty::Alias(
projection_ty @ ty::AliasTy { kind: ty::Projection { def_id }, .. },
) if !projection_ty.has_escaping_bound_vars()
&& !tcx.is_impl_trait_in_trait(def_id)
&& !self.next_trait_solver() =>
{
let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id));
let ty_var = self.next_ty_var(self.tcx.def_span(def_id));
goals.push(Goal::new(
self.tcx,
param_env,
@@ -334,11 +339,11 @@ pub fn add_item_bounds_for_hidden_type(
}
// Replace all other mentions of the same opaque type with the hidden type,
// as the bounds must hold on the hidden type after all.
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, args: args2, .. })
if def_id == def_id2 && args == args2 =>
{
hidden_ty
}
ty::Alias(ty::AliasTy {
kind: ty::Opaque { def_id: def_id2 },
args: args2,
..
}) if def_id == def_id2 && args == args2 => hidden_ty,
_ => ty,
},
lt_op: |lt| lt,
@@ -55,11 +55,11 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
// either `'static` or a unique outlives region, and if one is
// found, we just need to prove that that region is still live.
// If one is not found, then we continue to walk through the alias.
ty::Alias(kind, ty::AliasTy { def_id, args, .. }) => {
ty::Alias(ty::AliasTy { kind, args, .. }) => {
let tcx = self.tcx;
let param_env = self.param_env;
let outlives_bounds: Vec<_> = tcx
.item_bounds(def_id)
.item_bounds(kind.def_id())
.iter_instantiated(tcx, args)
.chain(param_env.caller_bounds())
.filter_map(|clause| {
@@ -93,7 +93,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
} else {
// Skip lifetime parameters that are not captured, since they do
// not need to be live.
let variances = tcx.opt_alias_variances(kind, def_id);
let variances = tcx.opt_alias_variances(kind, kind.def_id());
for (idx, s) in args.iter().enumerate() {
if variances.map(|variances| variances[idx]) != Some(ty::Bivariant) {
@@ -468,13 +468,13 @@ fn alias_ty_must_outlive(
// the problem is to add `T: 'r`, which isn't true. So, if there are no
// inference variables, we use a verify constraint instead of adding
// edges, which winds up enforcing the same condition.
let kind = alias_ty.kind(self.tcx);
let kind = alias_ty.kind;
if approx_env_bounds.is_empty()
&& trait_bounds.is_empty()
&& (alias_ty.has_infer_regions() || kind == ty::Opaque)
&& (alias_ty.has_infer_regions() || matches!(kind, ty::Opaque { .. }))
{
debug!("no declared bounds");
let opt_variances = self.tcx.opt_alias_variances(kind, alias_ty.def_id);
let opt_variances = self.tcx.opt_alias_variances(kind, kind.def_id());
self.args_must_outlive(alias_ty.args, origin, region, opt_variances);
return;
}
@@ -105,7 +105,7 @@ pub(crate) fn alias_bound(&self, alias_ty: ty::AliasTy<'tcx>) -> VerifyBound<'tc
// Search the env for where clauses like `P: 'a`.
let env_bounds = self.approx_declared_bounds_from_env(alias_ty).into_iter().map(|binder| {
if let Some(ty::OutlivesPredicate(ty, r)) = binder.no_bound_vars()
&& let ty::Alias(_, alias_ty_from_bound) = *ty.kind()
&& let ty::Alias(alias_ty_from_bound) = *ty.kind()
&& alias_ty_from_bound == alias_ty
{
// Micro-optimize if this is an exact match (this
@@ -126,8 +126,7 @@ pub(crate) fn alias_bound(&self, alias_ty: ty::AliasTy<'tcx>) -> VerifyBound<'tc
// see the extensive comment in projection_must_outlive
let recursive_bound = {
let mut components = smallvec![];
let kind = alias_ty.kind(self.tcx);
compute_alias_components_recursive(self.tcx, kind, alias_ty, &mut components);
compute_alias_components_recursive(self.tcx, alias_ty, &mut components);
self.bound_from_components(&components)
};
@@ -236,7 +235,8 @@ fn declared_generic_bounds_from_env_for_erased_ty(
// And therefore we can safely use structural equality for alias types.
(GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {}
(GenericKind::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => {}
(GenericKind::Alias(a1), ty::Alias(_, a2)) if a1.def_id == a2.def_id => {}
(GenericKind::Alias(a1), ty::Alias(a2)) if a1.kind.def_id() == a2.kind.def_id() => {
}
_ => return None,
}
@@ -281,7 +281,7 @@ pub(crate) fn declared_bounds_from_definition(
alias_ty: ty::AliasTy<'tcx>,
) -> impl Iterator<Item = ty::Region<'tcx>> {
let tcx = self.tcx;
let bounds = tcx.item_self_bounds(alias_ty.def_id);
let bounds = tcx.item_self_bounds(alias_ty.kind.def_id());
trace!("{:#?}", bounds.skip_binder());
bounds
.iter_instantiated(tcx, alias_ty.args)
@@ -635,7 +635,7 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
}
}
ty::Alias(_, data) => match self.structurally_relate_aliases {
ty::Alias(data) => match self.structurally_relate_aliases {
StructurallyRelateAliases::No => {
self.generalize_alias_term(data.into()).map(|v| v.expect_type())
}
@@ -161,12 +161,12 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
}
(
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: a_def_id }, .. }),
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: b_def_id }, .. }),
) if a_def_id == b_def_id => super_combine_tys(infcx, self, a, b),
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
(&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }), _)
| (_, &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }))
if def_id.is_local() && !infcx.next_trait_solver() =>
{
self.register_goals(infcx.handle_opaque_type(
@@ -184,14 +184,14 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
}
(
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: a_def_id }, .. }),
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: b_def_id }, .. }),
) if a_def_id == b_def_id => {
super_combine_tys(infcx, self, a, b)?;
}
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
(&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }), _)
| (_, &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }))
if self.define_opaque_types == DefineOpaqueTypes::Yes && def_id.is_local() =>
{
self.register_goals(infcx.handle_opaque_type(
+12 -3
View File
@@ -354,9 +354,18 @@ fn structurally_same_type_impl<'tcx>(
| (ty::Closure(..), ty::Closure(..))
| (ty::Coroutine(..), ty::Coroutine(..))
| (ty::CoroutineWitness(..), ty::CoroutineWitness(..))
| (ty::Alias(ty::Projection, ..), ty::Alias(ty::Projection, ..))
| (ty::Alias(ty::Inherent, ..), ty::Alias(ty::Inherent, ..))
| (ty::Alias(ty::Opaque, ..), ty::Alias(ty::Opaque, ..)) => false,
| (
ty::Alias(ty::AliasTy { kind: ty::Projection { .. }, .. }),
ty::Alias(ty::AliasTy { kind: ty::Projection { .. }, .. }),
)
| (
ty::Alias(ty::AliasTy { kind: ty::Inherent { .. }, .. }),
ty::Alias(ty::AliasTy { kind: ty::Inherent { .. }, .. }),
)
| (
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }),
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }),
) => false,
// These definitely should have been caught above.
(ty::Bool, ty::Bool)
+1 -1
View File
@@ -115,7 +115,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
}
ty::Adt(_, _)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Array(_, _)
| ty::Bound(_, _)
| ty::Closure(_, _)
@@ -242,16 +242,14 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
return;
}
if let ty::Alias(ty::Projection, opaque_ty) = *t.kind()
&& self.tcx.is_impl_trait_in_trait(opaque_ty.def_id)
if let ty::Alias(opaque_ty @ ty::AliasTy { kind: ty::Projection { def_id }, .. }) =
*t.kind()
&& self.tcx.is_impl_trait_in_trait(def_id)
{
// visit the opaque of the RPITIT
self.tcx
.type_of(opaque_ty.def_id)
.instantiate(self.tcx, opaque_ty.args)
.visit_with(self)
} else if let ty::Alias(ty::Opaque, opaque_ty) = *t.kind()
&& let Some(opaque_def_id) = opaque_ty.def_id.as_local()
self.tcx.type_of(def_id).instantiate(self.tcx, opaque_ty.args).visit_with(self)
} else if let ty::Alias(opaque_ty @ ty::AliasTy { kind: ty::Opaque { def_id}, .. }) = *t.kind()
&& let Some(opaque_def_id) = def_id.as_local()
// Don't recurse infinitely on an opaque
&& self.seen.insert(opaque_def_id)
// If it's owned by this function
@@ -415,9 +413,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
// in this lint as well. Interestingly, one place that I expect this lint to fire
// is for `impl for<'a> Bound<Out = impl Other>`, since `impl Other` will begin
// to capture `'a` in e2024 (even though late-bound vars in opaques are not allowed).
for clause in
self.tcx.item_bounds(opaque_ty.def_id).iter_instantiated(self.tcx, opaque_ty.args)
{
for clause in self.tcx.item_bounds(def_id).iter_instantiated(self.tcx, opaque_ty.args) {
clause.visit_with(self)
}
}
@@ -98,8 +98,9 @@ fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx, AmbigArg>
let Some(proj_term) = proj.term.as_type() else { return };
// HACK: `impl Trait<Assoc = impl Trait2>` from an RPIT is "ok"...
if let ty::Alias(ty::Opaque, opaque_ty) = *proj_term.kind()
&& cx.tcx.parent(opaque_ty.def_id) == def_id
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: opaque_def_id }, .. }) =
*proj_term.kind()
&& cx.tcx.parent(opaque_def_id) == def_id
&& matches!(
opaque.origin,
hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. }
@@ -171,7 +172,7 @@ fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx, AmbigArg>
// then we can emit a suggestion to add the bound.
let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
(
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }),
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }),
ty::ClauseKind::Trait(trait_pred),
) => Some(AddBound {
suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(),
@@ -671,17 +671,16 @@ fn visit_type(&mut self, state: VisitorState, ty: Ty<'tcx>) -> FfiResult<'tcx> {
// While opaque types are checked for earlier, if a projection in a struct field
// normalizes to an opaque type, then it will reach this branch.
ty::Alias(ty::Opaque, ..) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) => {
FfiUnsafe { ty, reason: msg!("opaque types have no C equivalent"), help: None }
}
// `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
// so they are currently ignored for the purposes of this lint.
ty::Param(..) | ty::Alias(ty::Projection | ty::Inherent, ..)
if state.can_expect_ty_params() =>
{
FfiSafe
}
ty::Param(..)
| ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. }, ..
}) if state.can_expect_ty_params() => FfiSafe,
ty::UnsafeBinder(_) => FfiUnsafe {
ty,
@@ -690,7 +689,10 @@ fn visit_type(&mut self, state: VisitorState, ty: Ty<'tcx>) -> FfiResult<'tcx> {
},
ty::Param(..)
| ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..)
| ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Free { .. },
..
})
| ty::Infer(..)
| ty::Bound(..)
| ty::Error(_)
@@ -713,7 +715,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
return ControlFlow::Continue(());
}
if let ty::Alias(ty::Opaque, ..) = ty.kind() {
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) = ty.kind() {
ControlFlow::Break(ty)
} else {
ty.super_visit_with(self)
+5 -2
View File
@@ -204,7 +204,10 @@ pub fn is_ty_must_use<'tcx>(
ty::Adt(def, _) => {
is_def_must_use(cx, def.did(), expr.span).map_or(IsTyMustUse::No, IsTyMustUse::Yes)
}
ty::Alias(ty::Opaque | ty::Projection, ty::AliasTy { def_id: def, .. }) => {
ty::Alias(ty::AliasTy {
kind: ty::Opaque { def_id: def } | ty::Projection { def_id: def },
..
}) => {
elaborate(cx.tcx, cx.tcx.explicit_item_self_bounds(def).iter_identity_copied())
// We only care about self bounds for the impl-trait
.filter_only_self()
@@ -316,7 +319,7 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
if let hir::ExprKind::Match(await_expr, _arms, hir::MatchSource::AwaitDesugar) = expr.kind
&& let ty = cx.typeck_results().expr_ty(await_expr)
&& let ty::Alias(ty::Opaque, ty::AliasTy { def_id: future_def_id, .. }) = ty.kind()
&& let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: future_def_id }, .. }) = ty.kind()
&& cx.tcx.ty_is_opaque_future(ty)
&& let async_fn_def_id = cx.tcx.parent(*future_def_id)
&& matches!(cx.tcx.def_kind(async_fn_def_id), DefKind::Fn | DefKind::AssocFn)
+3 -1
View File
@@ -2115,7 +2115,9 @@ pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident)
/// Given a `ty`, return whether it's an `impl Future<...>`.
pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind() else { return false };
let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
return false;
};
let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
@@ -187,6 +187,21 @@ fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
self.adt_def(adt_def_id)
}
fn alias_ty_kind_from_def_id(self, def_id: DefId) -> ty::AliasTyKind<'tcx> {
match self.def_kind(def_id) {
DefKind::AssocTy
if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) =>
{
ty::Inherent { def_id }
}
DefKind::AssocTy => ty::Projection { def_id },
DefKind::OpaqueTy => ty::Opaque { def_id },
DefKind::TyAlias => ty::Free { def_id },
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
}
}
fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
match self.def_kind(alias.def_id) {
DefKind::AssocTy => {
@@ -571,7 +586,7 @@ fn for_each_relevant_impl(
//
// Impls which apply to an alias after normalization are handled by
// `assemble_candidates_after_normalizing_self_ty`.
ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
ty::Alias(_) | ty::Placeholder(..) | ty::Error(_) => (),
// FIXME: These should ideally not exist as a self type. It would be nice for
// the builtin auto trait impls of coroutines to instead directly recurse
+5 -5
View File
@@ -627,11 +627,11 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
return ControlFlow::Break(());
}
Alias(Opaque, AliasTy { def_id, .. }) => {
Alias(AliasTy { kind: Opaque { def_id }, .. }) => {
let parent = self.tcx.parent(def_id);
let parent_ty = self.tcx.type_of(parent).instantiate_identity();
if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent)
&& let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) =
&& let Alias(AliasTy { kind: Opaque { def_id: parent_opaque_def_id }, .. }) =
*parent_ty.kind()
&& parent_opaque_def_id == def_id
{
@@ -641,7 +641,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
}
}
Alias(Projection, AliasTy { def_id, .. })
Alias(AliasTy { kind: Projection { def_id }, .. })
if self.tcx.def_kind(def_id) != DefKind::AssocTy =>
{
return ControlFlow::Break(());
@@ -714,12 +714,12 @@ fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
placeholder
}
Alias(Opaque, AliasTy { def_id, .. }) => {
Alias(AliasTy { kind: Opaque { def_id }, .. }) => {
let parent = self.tcx.parent(def_id);
let parent_ty = self.tcx.type_of(parent).instantiate_identity();
if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy =
self.tcx.def_kind(parent)
&& let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) =
&& let Alias(AliasTy { kind: Opaque { def_id: parent_opaque_def_id }, .. }) =
*parent_ty.kind()
&& parent_opaque_def_id == def_id
{
+10 -10
View File
@@ -148,14 +148,12 @@ pub fn sort_string(self, tcx: TyCtxt<'tcx>) -> Cow<'static, str> {
ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
ty::Alias(ty::Projection | ty::Inherent, _) => "associated type".into(),
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. }, ..
}) => "associated type".into(),
ty::Param(p) => format!("type parameter `{p}`").into(),
ty::Alias(ty::Opaque, ..) => {
if tcx.ty_is_opaque_future(self) {
"future".into()
} else {
"opaque type".into()
}
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) => {
if tcx.ty_is_opaque_future(self) { "future".into() } else { "opaque type".into() }
}
ty::Error(_) => "type error".into(),
_ => {
@@ -209,10 +207,12 @@ pub fn prefix_string(self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
ty::Tuple(..) => "tuple".into(),
ty::Placeholder(..) => "higher-ranked type".into(),
ty::Bound(..) => "bound type variable".into(),
ty::Alias(ty::Projection | ty::Inherent, _) => "associated type".into(),
ty::Alias(ty::Free, _) => "type alias".into(),
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. }, ..
}) => "associated type".into(),
ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. }) => "type alias".into(),
ty::Param(_) => "type parameter".into(),
ty::Alias(ty::Opaque, ..) => "opaque type".into(),
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) => "opaque type".into(),
}
}
}
@@ -109,16 +109,18 @@ pub fn inhabited_predicate(self, tcx: TyCtxt<'tcx>) -> InhabitedPredicate<'tcx>
InhabitedPredicate::True
}
Never => InhabitedPredicate::False,
Param(_) | Alias(ty::Inherent | ty::Projection | ty::Free, _) => {
InhabitedPredicate::GenericType(self)
}
Alias(ty::Opaque, alias_ty) => {
match alias_ty.def_id.as_local() {
Param(_)
| Alias(ty::AliasTy {
kind: ty::Inherent { .. } | ty::Projection { .. } | ty::Free { .. },
..
}) => InhabitedPredicate::GenericType(self),
&Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
match def_id.as_local() {
// Foreign opaque is considered inhabited.
None => InhabitedPredicate::True,
// Local opaque type may possibly be revealed.
Some(local_def_id) => {
let key = ty::OpaqueTypeKey { def_id: local_def_id, args: alias_ty.args };
let key = ty::OpaqueTypeKey { def_id: local_def_id, args };
InhabitedPredicate::OpaqueType(key)
}
}
+5 -1
View File
@@ -385,7 +385,11 @@ pub fn compute(
);
match tail.kind() {
ty::Param(_) | ty::Alias(ty::Projection | ty::Inherent, _) => {
ty::Param(_)
| ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. },
..
}) => {
debug_assert!(tail.has_non_region_param());
Ok(SizeSkeleton::Pointer {
non_zero,
+5 -5
View File
@@ -102,10 +102,10 @@
EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region, RegionKind, RegionVid,
};
pub use self::sty::{
AliasTy, Article, Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind,
BoundVariableKind, CanonicalPolyFnSig, CoroutineArgsExt, EarlyBinder, FnSig, InlineConstArgs,
InlineConstArgsParts, ParamConst, ParamTy, PlaceholderConst, PlaceholderRegion,
PlaceholderType, PolyFnSig, TyKind, TypeAndMut, TypingMode, UpvarArgs,
AliasTy, AliasTyKind, Article, Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy,
BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, CoroutineArgsExt, EarlyBinder, FnSig,
InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PlaceholderConst,
PlaceholderRegion, PlaceholderType, PolyFnSig, TyKind, TypeAndMut, TypingMode, UpvarArgs,
};
pub use self::trait_def::TraitDef;
pub use self::typeck_results::{
@@ -605,7 +605,7 @@ pub fn into_arg(self) -> GenericArg<'tcx> {
pub fn to_alias_term(self) -> Option<AliasTerm<'tcx>> {
match self.kind() {
TermKind::Ty(ty) => match *ty.kind() {
ty::Alias(_kind, alias_ty) => Some(alias_ty.into()),
ty::Alias(alias_ty) => Some(alias_ty.into()),
_ => None,
},
TermKind::Const(ct) => match ct.kind() {
+1 -1
View File
@@ -89,7 +89,7 @@ fn from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
MappingFlags::LITERAL | MappingFlags::IMPLICIT
}
ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Alias(_, _) | ty::Param(_) => {
ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Alias(_) | ty::Param(_) => {
MappingFlags::TO
}
+10 -5
View File
@@ -818,9 +818,14 @@ fn pretty_print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
}
}
ty::Foreign(def_id) => self.print_def_path(def_id, &[])?,
ty::Alias(ty::Projection | ty::Inherent | ty::Free, ref data) => data.print(self)?,
ty::Alias(
ref data @ ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Free { .. },
..
},
) => data.print(self)?,
ty::Placeholder(placeholder) => placeholder.print(self)?,
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
// We use verbose printing in 'NO_QUERIES' mode, to
// avoid needing to call `predicates_of`. This should
// only affect certain debug messages (e.g. messages printed
@@ -840,7 +845,7 @@ fn pretty_print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
DefKind::TyAlias | DefKind::AssocTy => {
// NOTE: I know we should check for NO_QUERIES here, but it's alright.
// `type_of` on a type alias or assoc type should never cause a cycle.
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) =
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: d }, .. }) =
*self.tcx().type_of(parent).instantiate_identity().kind()
{
if d == def_id {
@@ -1354,9 +1359,9 @@ fn pretty_print_rpitit(
let fn_args = if self.tcx().features().return_type_notation()
&& let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
self.tcx().opt_rpitit_info(def_id)
&& let ty::Alias(_, alias_ty) =
&& let ty::Alias(alias_ty) =
self.tcx().fn_sig(fn_def_id).skip_binder().output().skip_binder().kind()
&& alias_ty.def_id == def_id
&& alias_ty.kind.def_id() == def_id
&& let generics = self.tcx().generics_of(fn_def_id)
// FIXME(return_type_notation): We only support lifetime params for now.
&& generics.own_params.iter().all(|param| matches!(param.kind, ty::GenericParamDefKind::Lifetime))
@@ -133,7 +133,7 @@ pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Span> {
| ty::FnPtr(_, _)
| ty::Tuple(_)
| ty::Dynamic(_, _)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Bound(_, _)
| ty::Pat(_, _)
| ty::Placeholder(_)
@@ -366,7 +366,7 @@ fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
ty::CoroutineClosure(did, args) => {
ty::CoroutineClosure(did, args.try_fold_with(folder)?)
}
ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
ty::Alias(data) => ty::Alias(data.try_fold_with(folder)?),
ty::Pat(ty, pat) => ty::Pat(ty.try_fold_with(folder)?, pat.try_fold_with(folder)?),
ty::Bool
@@ -405,7 +405,7 @@ fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
ty::CoroutineWitness(did, args) => ty::CoroutineWitness(did, args.fold_with(folder)),
ty::Closure(did, args) => ty::Closure(did, args.fold_with(folder)),
ty::CoroutineClosure(did, args) => ty::CoroutineClosure(did, args.fold_with(folder)),
ty::Alias(kind, data) => ty::Alias(kind, data.fold_with(folder)),
ty::Alias(data) => ty::Alias(data.fold_with(folder)),
ty::Pat(ty, pat) => ty::Pat(ty.fold_with(folder), pat.fold_with(folder)),
ty::Bool
@@ -453,7 +453,7 @@ fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::
ty::CoroutineWitness(_did, args) => args.visit_with(visitor),
ty::Closure(_did, args) => args.visit_with(visitor),
ty::CoroutineClosure(_did, args) => args.visit_with(visitor),
ty::Alias(_, data) => data.visit_with(visitor),
ty::Alias(data) => data.visit_with(visitor),
ty::Pat(ty, pat) => {
try_visit!(ty.visit_with(visitor));
+10 -15
View File
@@ -471,7 +471,7 @@ pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType<'tcx>
#[inline]
pub fn new_alias(tcx: TyCtxt<'tcx>, alias_ty: ty::AliasTy<'tcx>) -> Ty<'tcx> {
debug_assert_matches!(
(kind, tcx.def_kind(alias_ty.kind.def_id())),
(alias_ty.kind, tcx.def_kind(alias_ty.kind.def_id())),
(ty::Opaque { .. }, DefKind::OpaqueTy)
| (ty::Projection { .. } | ty::Inherent { .. }, DefKind::AssocTy)
| (ty::Free { .. }, DefKind::TyAlias)
@@ -516,11 +516,7 @@ pub fn new_field_representing_type(
#[inline]
#[instrument(level = "debug", skip(tcx))]
pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
Ty::new_alias(
tcx,
ty::Opaque { def_id },
AliasTy::new_from_args(tcx, ty::Opaque { def_id }, args),
)
Ty::new_alias(tcx, AliasTy::new_from_args(tcx, ty::Opaque { def_id }, args))
}
/// Constructs a `TyKind::Error` type with current `ErrorGuaranteed`
@@ -776,7 +772,10 @@ pub fn new_projection_from_args(
item_def_id: DefId,
args: ty::GenericArgsRef<'tcx>,
) -> Ty<'tcx> {
Ty::new_alias(tcx, ty::Projection, AliasTy::new_from_args(tcx, item_def_id, args))
Ty::new_alias(
tcx,
AliasTy::new_from_args(tcx, ty::Projection { def_id: item_def_id }, args),
)
}
#[inline]
@@ -785,7 +784,7 @@ pub fn new_projection(
item_def_id: DefId,
args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
) -> Ty<'tcx> {
Ty::new_alias(tcx, ty::Projection, AliasTy::new(tcx, item_def_id, args))
Ty::new_alias(tcx, AliasTy::new(tcx, ty::Projection { def_id: item_def_id }, args))
}
#[inline]
@@ -961,12 +960,8 @@ fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: ty::BoundVar) -> Self {
Ty::new_canonical_bound(tcx, var)
}
fn new_alias(
interner: TyCtxt<'tcx>,
kind: ty::AliasTyKind,
alias_ty: ty::AliasTy<'tcx>,
) -> Self {
Ty::new_alias(interner, kind, alias_ty)
fn new_alias(interner: TyCtxt<'tcx>, alias_ty: ty::AliasTy<'tcx>) -> Self {
Ty::new_alias(interner, alias_ty)
}
fn new_error(interner: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
@@ -1600,7 +1595,7 @@ pub fn is_fn_ptr(self) -> bool {
#[inline]
pub fn is_impl_trait(self) -> bool {
matches!(self.kind(), Alias(ty::Opaque, ..))
matches!(self.kind(), Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }))
}
#[inline]
+6 -6
View File
@@ -913,18 +913,18 @@ pub fn expand_free_alias_tys<T: TypeFoldable<TyCtxt<'tcx>>>(self, value: T) -> T
/// [free]: ty::Free
/// [expand_free_alias_tys]: Self::expand_free_alias_tys
pub fn peel_off_free_alias_tys(self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
let ty::Alias(ty::Free, _) = ty.kind() else { return ty };
let ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. }) = ty.kind() else { return ty };
let limit = self.recursion_limit();
let mut depth = 0;
while let ty::Alias(ty::Free, alias) = ty.kind() {
while let &ty::Alias(ty::AliasTy { kind: ty::Free { def_id }, args, .. }) = ty.kind() {
if !limit.value_within_limit(depth) {
let guar = self.dcx().delayed_bug("overflow expanding free alias type");
return Ty::new_error(self, guar);
}
ty = self.type_of(alias.def_id).instantiate(self, alias.args);
ty = self.type_of(def_id).instantiate(self, args);
depth += 1;
}
@@ -1013,7 +1013,7 @@ fn cx(&self) -> TyCtxt<'tcx> {
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) = *t.kind() {
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) = *t.kind() {
self.expand_opaque_ty(def_id, args).unwrap_or(t)
} else if t.has_opaque_types() {
t.super_fold_with(self)
@@ -1057,7 +1057,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if !ty.has_type_flags(ty::TypeFlags::HAS_TY_FREE_ALIAS) {
return ty;
}
let ty::Alias(ty::Free, alias) = ty.kind() else {
let &ty::Alias(ty::AliasTy { kind: ty::Free { def_id }, args, .. }) = ty.kind() else {
return ty.super_fold_with(self);
};
if !self.tcx.recursion_limit().value_within_limit(self.depth) {
@@ -1067,7 +1067,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
self.depth += 1;
let ty = ensure_sufficient_stack(|| {
self.tcx.type_of(alias.def_id).instantiate(self.tcx, alias.args).fold_with(self)
self.tcx.type_of(def_id).instantiate(self.tcx, args).fold_with(self)
});
self.depth -= 1;
ty
+7 -2
View File
@@ -181,11 +181,16 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
// If we are only looking for "constrained" regions, we have to ignore the
// inputs to a projection as they may not appear in the normalized form.
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) => {
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Opaque { .. },
..
}) => {
return;
}
// All free alias types should've been expanded beforehand.
ty::Alias(ty::Free, _) => bug!("unexpected free alias type"),
ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. }) => {
bug!("unexpected free alias type")
}
_ => {}
}
}
@@ -333,7 +333,10 @@ fn ast_block_stmts(
// Opaque types of empty bodies also need this unit assignment, in order to infer that their
// type is actually unit. Otherwise there will be no defining use found in the MIR.
if destination_ty.is_unit()
|| matches!(destination_ty.kind(), ty::Alias(ty::Opaque, ..))
|| matches!(
destination_ty.kind(),
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. })
)
{
// We only want to assign an implicit `()` as the return value of the block if the
// block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
@@ -165,7 +165,7 @@ fn move_path_for<G>(&mut self, place: Place<'tcx>, mut on_move: G)
| ty::Never
| ty::Tuple(_)
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Infer(_)
@@ -205,7 +205,7 @@ fn move_path_for<G>(&mut self, place: Place<'tcx>, mut on_move: G)
| ty::CoroutineWitness(..)
| ty::Never
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Infer(_)
@@ -1900,7 +1900,7 @@ fn check_must_not_suspend_ty<'tcx>(
}
ty::Adt(def, _) => check_must_not_suspend_def(tcx, def.did(), hir_id, data),
// FIXME: support adding the attribute to TAITs
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: def }, .. }) => {
let mut has_emitted = false;
for &(predicate, _) in tcx.explicit_item_bounds(def).skip_binder() {
// We only look at the `DefId`, so it is safe to skip the binder here.
+1 -1
View File
@@ -242,7 +242,7 @@ fn maybe_drop_guard<'tcx>(
| ty::Dynamic(..)
| ty::Array(..)
| ty::Slice(..)
| ty::Alias(ty::Opaque, ..)
| ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. })
) && ty.needs_drop(tcx, typing_env)
} else {
false
+4 -2
View File
@@ -685,7 +685,7 @@ fn visit_projection_elem(
};
let kind = match parent_ty.ty.kind() {
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
self.tcx.type_of(def_id).instantiate(self.tcx, args).kind()
}
kind => kind,
@@ -1547,7 +1547,9 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
let pty = place.ty(&self.body.local_decls, self.tcx).ty;
if !matches!(
pty.kind(),
ty::Adt(..) | ty::Coroutine(..) | ty::Alias(ty::Opaque, ..)
ty::Adt(..)
| ty::Coroutine(..)
| ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. })
) {
self.fail(
location,
@@ -391,7 +391,7 @@ fn inner_fold_ty(&mut self, t: I::Ty) -> I::Ty {
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Bound(_, _)
| ty::Error(_) => {
return ensure_sufficient_stack(|| t.super_fold_with(self));
@@ -362,7 +362,7 @@ fn visit_ty(&mut self, ty: I::Ty) -> Self::Result {
// normalize to that, so we have to treat it as an uncovered ty param.
// * Otherwise it may normalize to any non-type-generic type
// be it local or non-local.
ty::Alias(kind, _) => {
ty::Alias(ty::AliasTy { kind, .. }) => {
if ty.has_type_flags(
ty::TypeFlags::HAS_TY_PLACEHOLDER
| ty::TypeFlags::HAS_TY_BOUND
@@ -370,7 +370,7 @@ fn visit_ty(&mut self, ty: I::Ty) -> Self::Result {
) {
match self.in_crate {
InCrate::Local { mode } => match kind {
ty::Projection => {
ty::Projection { .. } => {
if let OrphanCheckMode::Compat = mode {
ControlFlow::Continue(())
} else {
@@ -11,7 +11,7 @@
use rustc_type_ir::search_graph::CandidateHeadUsages;
use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind};
use rustc_type_ir::{
self as ty, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable,
self as ty, AliasTy, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
elaborate,
};
@@ -687,7 +687,7 @@ fn assemble_alias_bound_candidates_recur<G: GoalKind<D>>(
candidates: &mut Vec<Candidate<I>>,
consider_self_bounds: AliasBoundKind,
) {
let (kind, alias_ty) = match self_ty.kind() {
let alias_ty = match self_ty.kind() {
ty::Bool
| ty::Char
| ty::Int(_)
@@ -735,8 +735,10 @@ fn assemble_alias_bound_candidates_recur<G: GoalKind<D>>(
return;
}
ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
ty::Alias(ty::Inherent | ty::Free, _) => {
ty::Alias(
alias_ty @ AliasTy { kind: ty::Projection { .. } | ty::Opaque { .. }, .. },
) => alias_ty,
ty::Alias(AliasTy { kind: ty::Inherent { .. } | ty::Free { .. }, .. }) => {
self.cx().delay_bug(format!("could not normalize {self_ty:?}, it is not WF"));
return;
}
@@ -746,7 +748,7 @@ fn assemble_alias_bound_candidates_recur<G: GoalKind<D>>(
AliasBoundKind::SelfBounds => {
for assumption in self
.cx()
.item_self_bounds(alias_ty.def_id)
.item_self_bounds(alias_ty.kind.def_id())
.iter_instantiated(self.cx(), alias_ty.args)
{
candidates.extend(G::probe_and_consider_implied_clause(
@@ -761,7 +763,7 @@ fn assemble_alias_bound_candidates_recur<G: GoalKind<D>>(
AliasBoundKind::NonSelfBounds => {
for assumption in self
.cx()
.item_non_self_bounds(alias_ty.def_id)
.item_non_self_bounds(alias_ty.kind.def_id())
.iter_instantiated(self.cx(), alias_ty.args)
{
candidates.extend(G::probe_and_consider_implied_clause(
@@ -777,7 +779,7 @@ fn assemble_alias_bound_candidates_recur<G: GoalKind<D>>(
candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty));
if kind != ty::Projection {
if !matches!(alias_ty.kind, ty::Projection { .. }) {
return;
}
@@ -1023,7 +1025,7 @@ fn cx(&self) -> I {
self.cx
}
fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() {
if let ty::Alias(alias_ty) = ty.kind() {
if alias_ty == self.alias_ty {
return self.self_ty;
}
@@ -1041,7 +1043,7 @@ fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
// in a `?x: Trait<u32>` alias-bound candidate.
for item_bound in self
.cx()
.item_self_bounds(alias_ty.def_id)
.item_self_bounds(alias_ty.kind.def_id())
.iter_instantiated(self.cx(), alias_ty.args)
{
let assumption =
@@ -49,7 +49,10 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<D, I>(
ty::Dynamic(..)
| ty::Param(..)
| ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..)
| ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Free { .. },
..
})
| ty::Placeholder(..)
| ty::Bound(..)
| ty::Infer(_) => {
@@ -95,7 +98,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<D, I>(
Ok(ty::Binder::dummy(def.all_field_tys(cx).iter_instantiated(cx, args).collect()))
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
// We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring
// the auto trait bounds in question.
@@ -218,7 +221,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<D, I>(
| ty::Foreign(..)
| ty::Ref(_, _, Mutability::Mut)
| ty::Adt(_, _)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Placeholder(..) => Err(NoSolution),
@@ -390,7 +393,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
| ty::Tuple(_)
| ty::Pat(_, _)
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Placeholder(..)
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
@@ -563,7 +566,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
| ty::Never
| ty::UnsafeBinder(_)
| ty::Tuple(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Placeholder(..)
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
@@ -724,7 +727,7 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>(
| ty::Never
| ty::Tuple(_)
| ty::Pat(_, _)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Placeholder(..)
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
@@ -1014,7 +1017,7 @@ fn cx(&self) -> I {
}
fn try_fold_ty(&mut self, ty: I::Ty) -> Result<I::Ty, Ambiguous> {
if let ty::Alias(ty::Projection, alias_ty) = ty.kind()
if let ty::Alias(alias_ty @ ty::AliasTy { kind: ty::Projection { .. }, .. }) = ty.kind()
&& let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())?
{
Ok(term.expect_ty())
@@ -84,13 +84,13 @@ fn consider_additional_alias_assumptions(
let cx = ecx.cx();
let mut candidates = vec![];
if !ecx.cx().alias_has_const_conditions(alias_ty.def_id) {
if !ecx.cx().alias_has_const_conditions(alias_ty.kind.def_id()) {
return vec![];
}
for clause in elaborate::elaborate(
cx,
cx.explicit_implied_const_bounds(alias_ty.def_id)
cx.explicit_implied_const_bounds(alias_ty.kind.def_id())
.iter_instantiated(cx, alias_ty.args)
.map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.constness)),
) {
@@ -103,7 +103,7 @@ fn consider_additional_alias_assumptions(
// Const conditions must hold for the implied const bound to hold.
ecx.add_goals(
GoalSource::AliasBoundConstCondition,
cx.const_conditions(alias_ty.def_id)
cx.const_conditions(alias_ty.kind.def_id())
.iter_instantiated(cx, alias_ty.args)
.map(|trait_ref| {
goal.with(
@@ -653,7 +653,7 @@ fn consider_builtin_pointee_candidate(
.instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())])
}
ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => {
ty::Alias(_) | ty::Param(_) | ty::Placeholder(..) => {
// This is the "fallback impl" for type parameters, unnormalizable projections
// and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
// FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
@@ -910,7 +910,7 @@ fn consider_builtin_discriminant_kind_candidate(
// Given an alias, parameter, or placeholder we add an impl candidate normalizing to a rigid
// alias. In case there's a where-bound further constraining this alias it is preferred over
// this impl candidate anyways. It's still a bit scuffed.
ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => {
ty::Alias(_) | ty::Param(_) | ty::Placeholder(..) => {
return ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
@@ -230,9 +230,11 @@ fn consider_auto_trait_candidate(
// when merging candidates anyways.
//
// See tests/ui/impl-trait/auto-trait-leakage/avoid-query-cycle-via-item-bound.rs.
if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
debug_assert!(ecx.opaque_type_is_rigid(opaque_ty.def_id));
for item_bound in cx.item_self_bounds(opaque_ty.def_id).skip_binder() {
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) =
goal.predicate.self_ty().kind()
{
debug_assert!(ecx.opaque_type_is_rigid(def_id));
for item_bound in cx.item_self_bounds(def_id).skip_binder() {
if item_bound
.as_trait_clause()
.is_some_and(|b| b.def_id() == goal.predicate.def_id())
@@ -1249,7 +1251,10 @@ fn disqualify_auto_trait_candidate_due_to_possible_impl(
ty::Dynamic(..)
| ty::Param(..)
| ty::Foreign(..)
| ty::Alias(ty::Projection | ty::Free | ty::Inherent, ..)
| ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Free { .. } | ty::Inherent { .. },
..
})
| ty::Placeholder(..) => Some(Err(NoSolution)),
ty::Infer(_) | ty::Bound(_, _) => panic!("unexpected type `{self_ty:?}`"),
+1 -1
View File
@@ -308,7 +308,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
| ty::CoroutineWitness(_, _)
| ty::Never
| ty::UnsafeBinder(_)
| ty::Alias(ty::AliasTyKind::Opaque, _) => {
| ty::Alias(ty::AliasTy { kind: ty::AliasTyKind::Opaque { .. }, .. }) => {
return ControlFlow::Break(ty);
}
+7 -4
View File
@@ -126,8 +126,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
#[inline]
pub fn reveal_opaque_ty(&self, ty: Ty<'tcx>) -> RevealedTy<'tcx> {
fn reveal_inner<'tcx>(cx: &RustcPatCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> RevealedTy<'tcx> {
let ty::Alias(ty::Opaque, alias_ty) = *ty.kind() else { bug!() };
if let Some(local_def_id) = alias_ty.def_id.as_local() {
let ty::Alias(alias_ty @ ty::AliasTy { kind: ty::Opaque { .. }, .. }) = *ty.kind()
else {
bug!()
};
if let Some(local_def_id) = alias_ty.kind.def_id().as_local() {
let key = ty::OpaqueTypeKey { def_id: local_def_id, args: alias_ty.args };
if let Some(ty) = cx.reveal_opaque_key(key) {
return RevealedTy(ty);
@@ -135,7 +138,7 @@ fn reveal_inner<'tcx>(cx: &RustcPatCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> RevealedTy<'
}
RevealedTy(ty)
}
if let ty::Alias(ty::Opaque, _) = ty.kind() {
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) = ty.kind() {
reveal_inner(self, ty)
} else {
RevealedTy(ty)
@@ -423,7 +426,7 @@ pub fn ctors_for_ty(
| ty::CoroutineClosure(..)
| ty::Coroutine(_, _)
| ty::UnsafeBinder(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Error(_) => ConstructorSet::Unlistable,
ty::CoroutineWitness(_, _) | ty::Bound(_, _) | ty::Placeholder(_) | ty::Infer(_) => {
+16 -8
View File
@@ -209,7 +209,15 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
try_visit!(tcx.type_of(impl_def_id).instantiate_identity().visit_with(self));
}
}
ty::Alias(kind @ (ty::Inherent | ty::Free | ty::Projection), data) => {
ty::Alias(
data @ ty::AliasTy {
kind:
kind @ (ty::Inherent { def_id }
| ty::Free { def_id }
| ty::Projection { def_id }),
..
},
) => {
if self.def_id_visitor.skip_assoc_tys() {
// Visitors searching for minimal visibility/reachability want to
// conservatively approximate associated types like `Type::Alias`
@@ -226,19 +234,19 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
}
try_visit!(self.def_id_visitor.visit_def_id(
data.def_id,
def_id,
match kind {
ty::Inherent | ty::Projection => "associated type",
ty::Free => "type alias",
ty::Opaque => unreachable!(),
ty::Inherent { .. } | ty::Projection { .. } => "associated type",
ty::Free { .. } => "type alias",
ty::Opaque { .. } => unreachable!(),
},
&LazyDefPathStr { def_id: data.def_id, tcx },
&LazyDefPathStr { def_id, tcx },
));
// This will also visit args if necessary, so we don't need to recurse.
return if V::SHALLOW {
V::Result::output()
} else if kind == ty::Projection {
} else if matches!(kind, ty::Projection { .. }) {
self.visit_projection_term(data.into())
} else {
V::Result::from_branch(
@@ -261,7 +269,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
try_visit!(self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref));
}
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) => {
// Skip repeated `Opaque`s to avoid infinite recursion.
if self.visited_tys.insert(ty) {
// The intent is to treat `impl Trait1 + Trait2` identically to
@@ -12,14 +12,14 @@
};
use crate::unstable::Stable;
impl<'tcx> Stable<'tcx> for ty::AliasTyKind {
impl<'tcx> Stable<'tcx> for ty::AliasTyKind<'tcx> {
type T = crate::ty::AliasKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
ty::Projection => crate::ty::AliasKind::Projection,
ty::Inherent => crate::ty::AliasKind::Inherent,
ty::Opaque => crate::ty::AliasKind::Opaque,
ty::Free => crate::ty::AliasKind::Free,
ty::Projection { .. } => crate::ty::AliasKind::Projection,
ty::Inherent { .. } => crate::ty::AliasKind::Inherent,
ty::Opaque { .. } => crate::ty::AliasKind::Opaque,
ty::Free { .. } => crate::ty::AliasKind::Free,
}
}
}
@@ -31,8 +31,11 @@ fn stable<'cx>(
tables: &mut Tables<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::AliasTy { args, def_id, .. } = self;
crate::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables, cx) }
let ty::AliasTy { args, kind, .. } = self;
crate::ty::AliasTy {
def_id: tables.alias_def(kind.def_id()),
args: args.stable(tables, cx),
}
}
}
@@ -451,8 +454,8 @@ fn stable<'cx>(
ty::Tuple(fields) => TyKind::RigidTy(RigidTy::Tuple(
fields.iter().map(|ty| ty.stable(tables, cx)).collect(),
)),
ty::Alias(alias_kind, alias_ty) => {
TyKind::Alias(alias_kind.stable(tables, cx), alias_ty.stable(tables, cx))
ty::Alias(_alias_ty) => {
todo!()
}
ty::Param(param_ty) => TyKind::Param(param_ty.stable(tables, cx)),
ty::Bound(ty::BoundVarIndexKind::Canonical, _) => {
+1 -1
View File
@@ -117,7 +117,7 @@ fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
| ty::CoroutineWitness(_, _)
| ty::Never
| ty::Tuple(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Placeholder(_)
+8 -2
View File
@@ -242,7 +242,11 @@ fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
match *ty.kind() {
// Print all nominal types as paths (unlike `pretty_print_type`).
ty::FnDef(def_id, args)
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
| ty::Alias(ty::AliasTy {
kind: ty::Projection { def_id } | ty::Opaque { def_id },
args,
..
})
| ty::Closure(def_id, args)
| ty::CoroutineClosure(def_id, args)
| ty::Coroutine(def_id, args) => self.print_def_path(def_id, args),
@@ -264,7 +268,9 @@ fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
Ok(())
}
ty::Alias(ty::Inherent, _) => panic!("unexpected inherent projection"),
ty::Alias(ty::AliasTy { kind: ty::Inherent { .. }, .. }) => {
panic!("unexpected inherent projection")
}
_ => self.pretty_print_type(ty),
}
+1 -1
View File
@@ -539,7 +539,7 @@ fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
// We may still encounter projections here due to the printing
// logic sometimes passing identity-substituted impl headers.
ty::Alias(ty::Projection, ty::AliasTy { def_id, args, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Projection { def_id }, args, .. }) => {
self.print_def_path(def_id, args)?;
}
@@ -182,15 +182,15 @@ pub fn report_mismatched_consts(
pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
let (def_id, args) = match *ty.kind() {
ty::Alias(_, ty::AliasTy { def_id, args, .. })
if self.tcx.def_kind(def_id) == DefKind::OpaqueTy =>
ty::Alias(ty::AliasTy { kind, args, .. })
if self.tcx.def_kind(kind.def_id()) == DefKind::OpaqueTy =>
{
(def_id, args)
(kind.def_id(), args)
}
ty::Alias(_, ty::AliasTy { def_id, args, .. })
if self.tcx.is_impl_trait_in_trait(def_id) =>
ty::Alias(ty::AliasTy { kind, args, .. })
if self.tcx.is_impl_trait_in_trait(kind.def_id()) =>
{
(def_id, args)
(kind.def_id(), args)
}
_ => return None,
};
@@ -256,9 +256,13 @@ fn suggest_param_env_shadowing(
found: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) {
let (alias, concrete) = match (expected.kind(), found.kind()) {
(ty::Alias(ty::Projection, proj), _) => (proj, found),
(_, ty::Alias(ty::Projection, proj)) => (proj, expected),
let (alias, &def_id, concrete) = match (expected.kind(), found.kind()) {
(ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. }), _) => {
(proj, def_id, found)
}
(_, ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. })) => {
(proj, def_id, expected)
}
_ => return,
};
@@ -290,8 +294,7 @@ fn suggest_param_env_shadowing(
return false;
}
let leaf_def = match specialization_graph::assoc_def(tcx, impl_def_id, alias.def_id)
{
let leaf_def = match specialization_graph::assoc_def(tcx, impl_def_id, def_id) {
Ok(leaf) => leaf,
Err(_) => return false,
};
@@ -319,7 +322,7 @@ fn suggest_param_env_shadowing(
"the associated type `{}` is defined as `{}` in the implementation, \
but the where-bound `{}` shadows this definition\n\
see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information",
self.ty_to_string(tcx.mk_ty_from_kind(ty::Alias(ty::Projection, *alias))),
self.ty_to_string(tcx.mk_ty_from_kind(ty::Alias(*alias))),
self.ty_to_string(concrete),
self.ty_to_string(alias.self_ty())
));
@@ -1666,7 +1669,7 @@ enum Similar<'tcx> {
&& values.expected.sort_string(self.tcx)
!= values.found.sort_string(self.tcx);
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
(true, ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. })) => {
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
DiagStyledString::normal(format!(
@@ -1676,11 +1679,11 @@ enum Similar<'tcx> {
pos.col.to_usize() + 1,
))
}
(true, ty::Alias(ty::Projection, proj))
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
(true, &ty::Alias(ty::AliasTy { kind: ty::Projection { def_id }, .. }))
if self.tcx.is_impl_trait_in_trait(def_id) =>
{
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
let pos = sm.lookup_char_pos(self.tcx.def_span(def_id).lo());
DiagStyledString::normal(format!(
" (trait associated opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
@@ -2418,7 +2421,7 @@ impl TyCategory {
pub fn from_ty(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Self, DefId)> {
match *ty.kind() {
ty::Closure(def_id, _) => Some((Self::Closure, def_id)),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) => {
let kind =
if tcx.ty_is_opaque_future(ty) { Self::OpaqueFuture } else { Self::Opaque };
Some((kind, def_id))
@@ -1021,7 +1021,7 @@ fn generic_arg_contains_target(&self, arg: GenericArg<'tcx>) -> bool {
GenericArgKind::Type(ty) => {
if matches!(
ty.kind(),
ty::Alias(ty::Opaque, ..)
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. })
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
@@ -46,7 +46,10 @@ pub fn note_and_explain_type_err(
"consider pinning your async block and casting it to a trait object",
);
}
(ty::Alias(ty::Opaque, ..), ty::Alias(ty::Opaque, ..)) => {
(
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }),
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }),
) => {
// Issue #63167
diag.note("distinct uses of `impl Trait` result in different opaque types");
}
@@ -87,16 +90,27 @@ pub fn note_and_explain_type_err(
);
}
(
ty::Alias(ty::Projection | ty::Inherent, _),
ty::Alias(ty::Projection | ty::Inherent, _),
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. },
..
}),
ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. },
..
}),
) => {
diag.note("an associated type was expected, but a different one was found");
}
// FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
(ty::Param(p), ty::Alias(ty::Projection, proj))
| (ty::Alias(ty::Projection, proj), ty::Param(p))
if !tcx.is_impl_trait_in_trait(proj.def_id)
&& let Some(generics) = body_generics =>
(
ty::Param(p),
ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. }),
)
| (
ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. }),
ty::Param(p),
) if !tcx.is_impl_trait_in_trait(def_id)
&& let Some(generics) = body_generics =>
{
let param = generics.type_param(p, tcx);
let p_def_id = param.def_id;
@@ -123,7 +137,7 @@ pub fn note_and_explain_type_err(
// Synthesize the associated type restriction `Add<Output = Expected>`.
// FIXME: extract this logic for use in other diagnostics.
let (trait_ref, assoc_args) = proj.trait_ref_and_own_args(tcx);
let item_name = tcx.item_name(proj.def_id);
let item_name = tcx.item_name(def_id);
let item_args = self.format_generic_args(assoc_args);
// Here, we try to see if there's an existing
@@ -188,8 +202,14 @@ pub fn note_and_explain_type_err(
diag.note("you might be missing a type parameter or trait bound");
}
}
(ty::Param(p), ty::Dynamic(..) | ty::Alias(ty::Opaque, ..))
| (ty::Dynamic(..) | ty::Alias(ty::Opaque, ..), ty::Param(p)) => {
(
ty::Param(p),
ty::Dynamic(..) | ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }),
)
| (
ty::Dynamic(..) | ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }),
ty::Param(p),
) => {
if let Some(generics) = body_generics {
let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
let expected = match (values.expected.kind(), values.found.kind()) {
@@ -261,9 +281,15 @@ fn foo(&self, x: T) -> T { x }
diag.span_label(p_span, format!("{expected}this type parameter"));
}
}
(ty::Alias(ty::Projection | ty::Inherent, proj_ty), _)
if !tcx.is_impl_trait_in_trait(proj_ty.def_id) =>
{
(
ty::Alias(
proj_ty @ ty::AliasTy {
kind: ty::Projection { def_id } | ty::Inherent { def_id },
..
},
),
_,
) if !tcx.is_impl_trait_in_trait(def_id) => {
self.expected_projection(
diag,
proj_ty,
@@ -274,11 +300,18 @@ fn foo(&self, x: T) -> T { x }
}
// Don't suggest constraining a projection to something
// containing itself, e.g. `Item = &<I as Iterator>::Item`.
(_, ty::Alias(ty::Projection | ty::Inherent, proj_ty))
if !tcx.is_impl_trait_in_trait(proj_ty.def_id)
&& !tcx
.erase_and_anonymize_regions(values.expected)
.contains(tcx.erase_and_anonymize_regions(values.found)) =>
(
_,
ty::Alias(
proj_ty @ ty::AliasTy {
kind: ty::Projection { def_id } | ty::Inherent { def_id },
..
},
),
) if !tcx.is_impl_trait_in_trait(def_id)
&& !tcx
.erase_and_anonymize_regions(values.expected)
.contains(tcx.erase_and_anonymize_regions(values.found)) =>
{
let msg = || {
format!(
@@ -286,20 +319,20 @@ fn foo(&self, x: T) -> T { x }
values.found, values.expected,
)
};
let suggested_projection_constraint = proj_ty.kind(tcx)
== ty::AliasTyKind::Projection
&& (self.suggest_constraining_opaque_associated_type(
diag,
msg,
proj_ty,
values.expected,
) || self.suggest_constraint(
diag,
&msg,
body_owner_def_id,
proj_ty,
values.expected,
));
let suggested_projection_constraint =
matches!(proj_ty.kind, ty::Projection { .. })
&& (self.suggest_constraining_opaque_associated_type(
diag,
msg,
proj_ty,
values.expected,
) || self.suggest_constraint(
diag,
&msg,
body_owner_def_id,
proj_ty,
values.expected,
));
if !suggested_projection_constraint {
diag.help(msg());
diag.note(
@@ -308,21 +341,25 @@ fn foo(&self, x: T) -> T { x }
);
}
}
(ty::Dynamic(t, _), ty::Alias(ty::Opaque, alias))
if let Some(def_id) = t.principal_def_id()
&& tcx
.explicit_item_self_bounds(alias.def_id)
.skip_binder()
.iter()
.any(|(pred, _span)| match pred.kind().skip_binder() {
ty::ClauseKind::Trait(trait_predicate)
if trait_predicate.polarity
== ty::PredicatePolarity::Positive =>
{
trait_predicate.def_id() == def_id
}
_ => false,
}) =>
(
ty::Dynamic(t, _),
ty::Alias(ty::AliasTy {
kind: ty::Opaque { def_id: opaque_def_id }, ..
}),
) if let Some(def_id) = t.principal_def_id()
&& tcx
.explicit_item_self_bounds(opaque_def_id)
.skip_binder()
.iter()
.any(|(pred, _span)| match pred.kind().skip_binder() {
ty::ClauseKind::Trait(trait_predicate)
if trait_predicate.polarity
== ty::PredicatePolarity::Positive =>
{
trait_predicate.def_id() == def_id
}
_ => false,
}) =>
{
diag.help(format!(
"you can box the `{}` to coerce it to `Box<{}>`, but you'll have to \
@@ -367,10 +404,10 @@ fn foo(&self, x: T) -> T { x }
));
}
}
(_, ty::Alias(ty::Opaque, opaque_ty))
| (ty::Alias(ty::Opaque, opaque_ty), _) => {
(_, ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }))
| (ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }), _) => {
if let Some(body_owner_def_id) = body_owner_def_id
&& opaque_ty.def_id.is_local()
&& def_id.is_local()
&& matches!(
tcx.def_kind(body_owner_def_id),
DefKind::Fn
@@ -380,23 +417,23 @@ fn foo(&self, x: T) -> T { x }
| DefKind::AssocConst { .. }
)
&& matches!(
tcx.opaque_ty_origin(opaque_ty.def_id),
tcx.opaque_ty_origin(def_id),
hir::OpaqueTyOrigin::TyAlias { .. }
)
&& !tcx
.opaque_types_defined_by(body_owner_def_id.expect_local())
.contains(&opaque_ty.def_id.expect_local())
.contains(&def_id.expect_local())
{
let sp = tcx
.def_ident_span(body_owner_def_id)
.unwrap_or_else(|| tcx.def_span(body_owner_def_id));
let mut alias_def_id = opaque_ty.def_id;
let mut alias_def_id = def_id;
while let DefKind::OpaqueTy = tcx.def_kind(alias_def_id) {
alias_def_id = tcx.parent(alias_def_id);
}
let opaque_path = tcx.def_path_str(alias_def_id);
// FIXME(type_alias_impl_trait): make this a structured suggestion
match tcx.opaque_ty_origin(opaque_ty.def_id) {
match tcx.opaque_ty_origin(def_id) {
rustc_hir::OpaqueTyOrigin::FnReturn { .. } => {}
rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {}
rustc_hir::OpaqueTyOrigin::TyAlias {
@@ -448,7 +485,7 @@ fn foo(&self, x: T) -> T { x }
ty::Alias(..) => values.expected,
_ => values.found,
};
let preds = tcx.explicit_item_self_bounds(opaque_ty.def_id);
let preds = tcx.explicit_item_self_bounds(def_id);
for (pred, _span) in preds.skip_binder() {
let ty::ClauseKind::Trait(trait_predicate) = pred.kind().skip_binder()
else {
@@ -572,7 +609,7 @@ fn suggest_constraint(
let Some(body_owner_def_id) = body_owner_def_id else {
return false;
};
let assoc = tcx.associated_item(proj_ty.def_id);
let assoc = tcx.associated_item(proj_ty.kind.def_id());
let (trait_ref, assoc_args) = proj_ty.trait_ref_and_own_args(tcx);
let Some(item) = tcx.hir_get_if_local(body_owner_def_id) else {
return false;
@@ -680,9 +717,9 @@ fn expected_projection(
let point_at_assoc_fn = if callable_scope
&& self.point_at_methods_that_satisfy_associated_type(
diag,
tcx.parent(proj_ty.def_id),
tcx.parent(proj_ty.kind.def_id()),
current_method_ident,
proj_ty.def_id,
proj_ty.kind.def_id(),
values.expected,
) {
// If we find a suitable associated function that returns the expected type, we
@@ -755,8 +792,10 @@ fn suggest_constraining_opaque_associated_type(
) -> bool {
let tcx = self.tcx;
let assoc = tcx.associated_item(proj_ty.def_id);
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() {
let assoc = tcx.associated_item(proj_ty.kind.def_id());
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) =
*proj_ty.self_ty().kind()
{
let opaque_local_def_id = def_id.as_local();
let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id {
tcx.hir_expect_opaque_ty(opaque_local_def_id)
@@ -805,14 +844,12 @@ fn point_at_methods_that_satisfy_associated_type(
.filter_map(|item| {
let method = tcx.fn_sig(item.def_id).instantiate_identity();
match *method.output().skip_binder().kind() {
ty::Alias(ty::Projection, ty::AliasTy { def_id: item_def_id, .. })
if item_def_id == proj_ty_item_def_id =>
{
Some((
tcx.def_span(item.def_id),
format!("consider calling `{}`", tcx.def_path_str(item.def_id)),
))
}
ty::Alias(ty::AliasTy {
kind: ty::Projection { def_id: item_def_id }, ..
}) if item_def_id == proj_ty_item_def_id => Some((
tcx.def_span(item.def_id),
format!("consider calling `{}`", tcx.def_path_str(item.def_id)),
)),
_ => None,
}
})
@@ -719,12 +719,12 @@ pub fn construct_generic_bound_failure(
let labeled_user_string = match bound_kind {
GenericKind::Param(_) => format!("the parameter type `{bound_kind}`"),
GenericKind::Placeholder(_) => format!("the placeholder type `{bound_kind}`"),
GenericKind::Alias(p) => match p.kind(self.tcx) {
ty::Projection | ty::Inherent => {
GenericKind::Alias(p) => match p.kind {
ty::Projection { .. } | ty::Inherent { .. } => {
format!("the associated type `{bound_kind}`")
}
ty::Free => format!("the type alias `{bound_kind}`"),
ty::Opaque => format!("the opaque type `{bound_kind}`"),
ty::Free { .. } => format!("the type alias `{bound_kind}`"),
ty::Opaque { .. } => format!("the opaque type `{bound_kind}`"),
},
};
@@ -846,10 +846,10 @@ pub fn construct_generic_bound_failure(
LifetimeSuggestion::HasColon => suggs.push((sp, format!(" {lt_name}"))),
}
} else if let GenericKind::Alias(ref p) = bound_kind
&& let ty::Projection = p.kind(self.tcx)
&& let DefKind::AssocTy = self.tcx.def_kind(p.def_id)
&& let ty::Projection { def_id } = p.kind
&& let DefKind::AssocTy = self.tcx.def_kind(def_id)
&& let Some(ty::ImplTraitInTraitData::Trait { .. }) =
self.tcx.opt_rpitit_info(p.def_id)
self.tcx.opt_rpitit_info(def_id)
{
// The lifetime found in the `impl` is longer than the one on the RPITIT.
// Do not suggest `<Type as Trait>::{opaque}: 'static`.
@@ -767,12 +767,20 @@ fn could_remove_semicolon(
StatementAsExpression::CorrectType
}
(
ty::Alias(ty::Opaque, ty::AliasTy { def_id: last_def_id, .. }),
ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, .. }),
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: last_def_id }, .. }),
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: exp_def_id }, .. }),
) if last_def_id == exp_def_id => StatementAsExpression::CorrectType,
(
ty::Alias(ty::Opaque, ty::AliasTy { def_id: last_def_id, args: last_bounds, .. }),
ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, args: exp_bounds, .. }),
ty::Alias(ty::AliasTy {
kind: ty::Opaque { def_id: last_def_id },
args: last_bounds,
..
}),
ty::Alias(ty::AliasTy {
kind: ty::Opaque { def_id: exp_def_id },
args: exp_bounds,
..
}),
) => {
debug!(
"both opaque, likely future {:?} {:?} {:?} {:?}",
@@ -1877,10 +1877,10 @@ fn type_category(tcx: TyCtxt<'_>, t: Ty<'_>) -> Option<u32> {
ty::Closure(..) => Some(9),
ty::Tuple(..) => Some(10),
ty::Param(..) => Some(11),
ty::Alias(ty::Projection, ..) => Some(12),
ty::Alias(ty::Inherent, ..) => Some(13),
ty::Alias(ty::Opaque, ..) => Some(14),
ty::Alias(ty::Free, ..) => Some(15),
ty::Alias(ty::AliasTy { kind: ty::Projection { .. }, .. }) => Some(12),
ty::Alias(ty::AliasTy { kind: ty::Inherent { .. }, .. }) => Some(13),
ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) => Some(14),
ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. }) => Some(15),
ty::Never => Some(16),
ty::Adt(..) => Some(17),
ty::Coroutine(..) => Some(18),
@@ -139,9 +139,11 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
if hir_generics.where_clause_span.from_expansion()
|| hir_generics.where_clause_span.desugaring_kind().is_some()
|| projection.is_some_and(|projection| {
(tcx.is_impl_trait_in_trait(projection.def_id)
(tcx.is_impl_trait_in_trait(projection.kind.def_id())
&& !tcx.features().return_type_notation())
|| tcx.lookup_stability(projection.def_id).is_some_and(|stab| stab.is_unstable())
|| tcx
.lookup_stability(projection.kind.def_id())
.is_some_and(|stab| stab.is_unstable())
})
{
return;
@@ -467,7 +469,9 @@ pub fn suggest_restricting_param_bound(
let self_ty = trait_pred.skip_binder().self_ty();
let (param_ty, projection) = match *self_ty.kind() {
ty::Param(_) => (true, None),
ty::Alias(ty::Projection, projection) => (false, Some(projection)),
ty::Alias(projection @ ty::AliasTy { kind: ty::Projection { .. }, .. }) => {
(false, Some(projection))
}
_ => (false, None),
};
@@ -1365,7 +1369,7 @@ pub fn extract_callable_info(
sig_parts.map_bound(|sig| sig.tupled_inputs_ty.tuple_fields().as_slice()),
))
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
self.tcx.item_self_bounds(def_id).instantiate(self.tcx, args).iter().find_map(
|pred| {
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
@@ -3702,7 +3706,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
}
}
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) => {
// If the previous type is async fn, this is the future generated by the body of an async function.
// Avoid printing it twice (it was already printed in the `ty::Coroutine` arm below).
let is_future = tcx.ty_is_opaque_future(ty);
@@ -4987,14 +4991,16 @@ fn probe_assoc_types_at_expr(
let TypeError::Sorts(expected_found) = diff else {
continue;
};
let ty::Alias(ty::Projection, proj) = expected_found.expected.kind() else {
let ty::Alias(ty::AliasTy { kind: ty::Projection { def_id }, .. }) =
expected_found.expected.kind()
else {
continue;
};
// Make `Self` be equivalent to the type of the call chain
// expression we're looking at now, so that we can tell what
// for example `Iterator::Item` is at this point in the chain.
let args = GenericArgs::for_item(self.tcx, proj.def_id, |param, _| {
let args = GenericArgs::for_item(self.tcx, *def_id, |param, _| {
if param.index == 0 {
debug_assert_matches!(param.kind, ty::GenericParamDefKind::Type { .. });
return prev_ty.into();
@@ -5008,7 +5014,7 @@ fn probe_assoc_types_at_expr(
// This corresponds to `<ExprTy as Iterator>::Item = _`.
let projection = ty::Binder::dummy(ty::PredicateKind::Clause(
ty::ClauseKind::Projection(ty::ProjectionPredicate {
projection_term: ty::AliasTerm::new_from_args(self.tcx, proj.def_id, args),
projection_term: ty::AliasTerm::new_from_args(self.tcx, *def_id, args),
term: ty.into(),
}),
));
@@ -5025,7 +5031,7 @@ fn probe_assoc_types_at_expr(
&& let ty = self.resolve_vars_if_possible(ty)
&& !ty.is_ty_var()
{
assocs_in_this_method.push(Some((span, (proj.def_id, ty))));
assocs_in_this_method.push(Some((span, (*def_id, ty))));
} else {
// `<ExprTy as Iterator>` didn't select, so likely we've
// reached the end of the iterator chain, like the originating
@@ -5309,11 +5315,13 @@ pub(super) fn suggest_desugaring_async_fn_in_trait(
}
// Look for an RPITIT
let ty::Alias(ty::Projection, alias_ty) = trait_pred.self_ty().skip_binder().kind() else {
let ty::Alias(alias_ty @ ty::AliasTy { kind: ty::Projection { def_id }, .. }) =
trait_pred.self_ty().skip_binder().kind()
else {
return;
};
let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
self.tcx.opt_rpitit_info(alias_ty.def_id)
self.tcx.opt_rpitit_info(*def_id)
else {
return;
};
@@ -546,14 +546,16 @@ fn is_param_no_infer(&self, args: GenericArgsRef<'tcx>) -> bool {
pub fn is_of_param(&self, ty: Ty<'tcx>) -> bool {
match ty.kind() {
ty::Param(_) => true,
ty::Alias(ty::Projection, p) => self.is_of_param(p.self_ty()),
ty::Alias(p @ ty::AliasTy { kind: ty::Projection { .. }, .. }) => {
self.is_of_param(p.self_ty())
}
_ => false,
}
}
fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'tcx>) -> bool {
if let Some(ty) = p.term().skip_binder().as_type() {
matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_term.expect_ty(self.tcx))
matches!(ty.kind(), ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { .. }, .. }) if proj == &p.skip_binder().projection_term.expect_ty(self.tcx))
} else {
false
}
@@ -811,11 +811,13 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
ControlFlow::Continue(())
}
}
ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => {
ty::Alias(ty::AliasTy { kind: ty::Projection { def_id }, .. })
if self.tcx.is_impl_trait_in_trait(*def_id) =>
{
// We'll deny these later in their own pass
ControlFlow::Continue(())
}
ty::Alias(ty::Projection, proj) => {
ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { .. }, .. }) => {
match self.allow_self_projections {
AllowSelfProjections::Yes => {
// Only walk contained types if the parent trait is not a supertrait.
@@ -914,12 +916,12 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalRpititVisitor<'tcx> {
type Result = ControlFlow<MethodViolation>;
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
if let ty::Alias(ty::Projection, proj) = *ty.kind()
if let ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. }) = *ty.kind()
&& Some(proj) != self.allowed
&& self.tcx.is_impl_trait_in_trait(proj.def_id)
&& self.tcx.is_impl_trait_in_trait(def_id)
{
ControlFlow::Break(MethodViolation::ReferencesImplTraitInTrait(
self.tcx.def_span(proj.def_id),
self.tcx.def_span(def_id),
))
} else {
ty.super_visit_with(self)
@@ -178,11 +178,17 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>(
let mut candidate = None;
let mut consider_ty = obligation.predicate.self_ty();
while let ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) = *consider_ty.kind() {
if tcx.is_conditionally_const(alias_ty.def_id) {
while let ty::Alias(
alias_ty @ ty::AliasTy {
kind: kind @ (ty::Projection { def_id } | ty::Opaque { def_id }),
..
},
) = *consider_ty.kind()
{
if tcx.is_conditionally_const(def_id) {
for clause in elaborate(
tcx,
tcx.explicit_implied_const_bounds(alias_ty.def_id)
tcx.explicit_implied_const_bounds(def_id)
.iter_instantiated_copied(tcx, alias_ty.args)
.map(|(trait_ref, _)| {
trait_ref.to_host_effect_clause(tcx, obligation.predicate.constness)
@@ -217,7 +223,7 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>(
}
}
if kind != ty::Projection {
if !matches!(kind, ty::Projection { .. }) {
break;
}
@@ -233,7 +239,7 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>(
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth,
tcx.const_conditions(alias_ty.def_id).instantiate(tcx, alias_ty.args),
tcx.const_conditions(alias_ty.kind.def_id()).instantiate(tcx, alias_ty.args),
nested,
);
nested.extend(const_conditions.into_iter().map(|(trait_ref, _)| {
@@ -259,8 +265,14 @@ fn evaluate_host_effect_from_item_bounds<'tcx>(
let mut candidate = None;
let mut consider_ty = obligation.predicate.self_ty();
while let ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) = *consider_ty.kind() {
for clause in tcx.item_bounds(alias_ty.def_id).iter_instantiated(tcx, alias_ty.args) {
while let ty::Alias(
alias_ty @ ty::AliasTy {
kind: kind @ (ty::Projection { def_id } | ty::Opaque { def_id }),
..
},
) = *consider_ty.kind()
{
for clause in tcx.item_bounds(def_id).iter_instantiated(tcx, alias_ty.args) {
let bound_clause = clause.kind();
let ty::ClauseKind::HostEffect(data) = bound_clause.skip_binder() else {
continue;
@@ -289,7 +301,7 @@ fn evaluate_host_effect_from_item_bounds<'tcx>(
}
}
if kind != ty::Projection {
if !matches!(kind, ty::Projection { .. }) {
break;
}
@@ -352,7 +364,7 @@ fn evaluate_host_effect_for_copy_clone_goal<'tcx>(
| ty::Foreign(..)
| ty::Ref(_, _, ty::Mutability::Mut)
| ty::Adt(_, _)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Placeholder(..) => Err(EvaluationFailure::NoSolution),
@@ -366,10 +366,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
return ty;
}
let (kind, data) = match *ty.kind() {
ty::Alias(kind, data) => (kind, data),
_ => return ty.super_fold_with(self),
};
let ty::Alias(data) = *ty.kind() else { return ty.super_fold_with(self) };
// We try to be a little clever here as a performance optimization in
// cases where there are nested projections under binders.
@@ -394,8 +391,8 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
// replace bound vars if the current type is a `Projection` and we need
// to make sure we don't forget to fold the args regardless.
match kind {
ty::Opaque => {
match data.kind {
ty::Opaque { def_id } => {
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.selcx.infcx.typing_mode() {
// FIXME(#132279): We likely want to reveal opaques during post borrowck analysis
@@ -415,7 +412,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
}
let args = data.args.fold_with(self);
let generic_ty = self.cx().type_of(data.def_id);
let generic_ty = self.cx().type_of(def_id);
let concrete_ty = generic_ty.instantiate(self.cx(), args);
self.depth += 1;
let folded_ty = self.fold_ty(concrete_ty);
@@ -425,9 +422,9 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
}
}
ty::Projection => self.normalize_trait_projection(data.into()).expect_type(),
ty::Inherent => self.normalize_inherent_projection(data.into()).expect_type(),
ty::Free => self.normalize_free_alias(data.into()).expect_type(),
ty::Projection { .. } => self.normalize_trait_projection(data.into()).expect_type(),
ty::Inherent { .. } => self.normalize_inherent_projection(data.into()).expect_type(),
ty::Free { .. } => self.normalize_free_alias(data.into()).expect_type(),
}
}
@@ -202,19 +202,16 @@ fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
return Ok(*ty);
}
let (kind, data) = match *ty.kind() {
ty::Alias(kind, data) => (kind, data),
_ => {
let res = ty.try_super_fold_with(self)?;
self.cache.insert(ty, res);
return Ok(res);
}
let &ty::Alias(data) = ty.kind() else {
let res = ty.try_super_fold_with(self)?;
self.cache.insert(ty, res);
return Ok(res);
};
// See note in `rustc_trait_selection::traits::project` about why we
// wait to fold the args.
let res = match kind {
ty::Opaque => {
let res = match data.kind {
ty::Opaque { .. } => {
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.infcx.typing_mode() {
TypingMode::Coherence
@@ -239,7 +236,7 @@ fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
return Ok(Ty::new_error(self.cx(), guar));
}
let generic_ty = self.cx().type_of(data.def_id);
let generic_ty = self.cx().type_of(data.kind.def_id());
let mut concrete_ty = generic_ty.instantiate(self.cx(), args);
self.anon_depth += 1;
if concrete_ty == ty {
@@ -256,8 +253,8 @@ fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
}
}
ty::Projection | ty::Inherent | ty::Free => self
.try_fold_free_or_assoc(ty::AliasTerm::new(self.cx(), data.def_id, data.args))?
ty::Projection { def_id } | ty::Inherent { def_id } | ty::Free { def_id } => self
.try_fold_free_or_assoc(ty::AliasTerm::new(self.cx(), def_id, data.args))?
.expect_type(),
};
@@ -194,7 +194,7 @@ fn assemble_candidates_from_projected_tys(
// quickly check if the self-type is a projection at all.
match obligation.predicate.skip_binder().trait_ref.self_ty().kind() {
// Excluding IATs and type aliases here as they don't have meaningful item bounds.
ty::Alias(ty::Projection | ty::Opaque, _) => {}
ty::Alias(ty::AliasTy { kind: ty::Projection { .. } | ty::Opaque { .. }, .. }) => {}
ty::Infer(ty::TyVar(_)) => {
span_bug!(
obligation.cause.span,
@@ -681,7 +681,7 @@ fn reject_fn_ptr_impls(
// These may potentially implement `FnPtr`
ty::Placeholder(..)
| ty::Dynamic(_, _)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Infer(_)
| ty::Param(..)
| ty::Bound(_, _) => {}
@@ -784,7 +784,10 @@ fn assemble_candidates_from_auto_impls(
}
}
ty::Param(..)
| ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..)
| ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Free { .. },
..
})
| ty::Placeholder(..)
| ty::Bound(..) => {
// In these cases, we don't know what the actual
@@ -835,7 +838,7 @@ fn assemble_candidates_from_auto_impls(
);
}
ty::Alias(ty::Opaque, alias) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) => {
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate { .. })) {
// We do not generate an auto impl candidate for `impl Trait`s which already
// reference our auto trait.
@@ -850,7 +853,7 @@ fn assemble_candidates_from_auto_impls(
// We do not emit auto trait candidates for opaque types in coherence.
// Doing so can result in weird dependency cycles.
candidates.ambiguous = true;
} else if self.infcx.can_define_opaque_ty(alias.def_id) {
} else if self.infcx.can_define_opaque_ty(def_id) {
// We do not emit auto trait candidates for opaque types in their defining scope, as
// we need to know the hidden type first, which we can't reliably know within the defining
// scope.
@@ -1643,8 +1643,13 @@ pub(super) fn for_each_item_bound<T>(
let mut alias_bound_kind = AliasBoundKind::SelfBounds;
loop {
let (kind, alias_ty) = match *self_ty.kind() {
ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
let (alias_ty, def_id) = match *self_ty.kind() {
ty::Alias(
alias_ty @ ty::AliasTy {
kind: ty::Projection { def_id } | ty::Opaque { def_id },
..
},
) => (alias_ty, def_id),
ty::Infer(ty::TyVar(_)) => {
on_ambiguity();
return ControlFlow::Continue(());
@@ -1657,9 +1662,9 @@ pub(super) fn for_each_item_bound<T>(
// projections, we will never be able to equate, e.g. `<T as Tr>::A`
// with `<<T as Tr>::A as Tr>::A`.
let relevant_bounds = if alias_bound_kind == AliasBoundKind::NonSelfBounds {
self.tcx().item_non_self_bounds(alias_ty.def_id)
self.tcx().item_non_self_bounds(def_id)
} else {
self.tcx().item_self_bounds(alias_ty.def_id)
self.tcx().item_self_bounds(def_id)
};
for bound in relevant_bounds.instantiate(self.tcx(), alias_ty.args) {
@@ -1667,7 +1672,7 @@ pub(super) fn for_each_item_bound<T>(
idx += 1;
}
if kind == ty::Projection {
if matches!(alias_ty.kind, ty::Projection { .. }) {
self_ty = alias_ty.self_ty();
} else {
return ControlFlow::Continue(());
@@ -2328,7 +2333,10 @@ fn constituent_types_for_auto_trait(
ty::Placeholder(..)
| ty::Dynamic(..)
| ty::Param(..)
| ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..)
| ty::Alias(ty::AliasTy {
kind: ty::Projection { .. } | ty::Inherent { .. } | ty::Free { .. },
..
})
| ty::Bound(..)
| ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("asked to assemble constituent types of unexpected type: {:?}", t);
@@ -2396,7 +2404,7 @@ fn constituent_types_for_auto_trait(
assumptions: vec![],
}),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
if self.infcx.can_define_opaque_ty(def_id) {
unreachable!()
} else {
@@ -285,9 +285,8 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
};
let ty_to_impl_span = |ty: Ty<'_>| {
if let ty::Alias(ty::Projection, projection_ty) = ty.kind()
&& let Some(&impl_item_id) =
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id)
if let ty::Alias(ty::AliasTy { kind: ty::Projection { def_id }, .. }) = ty.kind()
&& let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(def_id)
&& let Some(impl_item) =
items.iter().find(|item| item.owner_id.to_def_id() == impl_item_id)
{
@@ -798,11 +797,15 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
// Simple cases that are WF if their type args are WF.
}
ty::Alias(ty::Projection | ty::Opaque | ty::Free, data) => {
let obligations = self.nominal_obligations(data.def_id, data.args);
ty::Alias(ty::AliasTy {
kind: ty::Projection { def_id } | ty::Opaque { def_id } | ty::Free { def_id },
args,
..
}) => {
let obligations = self.nominal_obligations(def_id, args);
self.out.extend(obligations);
}
ty::Alias(ty::Inherent, data) => {
ty::Alias(data @ ty::AliasTy { kind: ty::Inherent { .. }, .. }) => {
self.add_wf_preds_for_inherent_projection(data.into());
return; // Subtree handled by compute_inherent_projection.
}
+25 -18
View File
@@ -92,12 +92,12 @@ fn visit_nested_body(&mut self, id: rustc_hir::BodyId) {
#[instrument(level = "debug", skip(self))]
fn visit_opaque_ty(&mut self, alias_ty: ty::AliasTy<'tcx>) {
if !self.seen.insert(alias_ty.def_id.expect_local()) {
if !self.seen.insert(alias_ty.kind.def_id().expect_local()) {
return;
}
// TAITs outside their defining scopes are ignored.
match self.tcx.local_opaque_ty_origin(alias_ty.def_id.expect_local()) {
match self.tcx.local_opaque_ty_origin(alias_ty.kind.def_id().expect_local()) {
rustc_hir::OpaqueTyOrigin::FnReturn { .. }
| rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {}
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => match self.mode {
@@ -122,9 +122,9 @@ fn visit_opaque_ty(&mut self, alias_ty: ty::AliasTy<'tcx>) {
}
trace!(?alias_ty, "adding");
self.opaques.push(alias_ty.def_id.expect_local());
self.opaques.push(alias_ty.kind.def_id().expect_local());
let parent_count = self.tcx.generics_of(alias_ty.def_id).parent_count;
let parent_count = self.tcx.generics_of(alias_ty.kind.def_id()).parent_count;
// Only check that the parent generics of the TAIT/RPIT are unique.
// the args owned by the opaque are going to always be duplicate
// lifetime params for RPITs, and empty for TAITs.
@@ -141,7 +141,7 @@ fn visit_opaque_ty(&mut self, alias_ty: ty::AliasTy<'tcx>) {
// We use identity args here, because we already know that the opaque type uses
// only generic parameters, and thus instantiating would not give us more information.
for (pred, span) in
self.tcx.explicit_item_bounds(alias_ty.def_id).iter_identity_copied()
self.tcx.explicit_item_bounds(alias_ty.kind.def_id()).iter_identity_copied()
{
trace!(?pred);
self.visit_spanned(span, pred);
@@ -151,14 +151,14 @@ fn visit_opaque_ty(&mut self, alias_ty: ty::AliasTy<'tcx>) {
self.tcx.dcx().emit_err(NotParam {
arg,
span: self.span(),
opaque_span: self.tcx.def_span(alias_ty.def_id),
opaque_span: self.tcx.def_span(alias_ty.kind.def_id()),
});
}
Err(NotUniqueParam::DuplicateParam(arg)) => {
self.tcx.dcx().emit_err(DuplicateArg {
arg,
span: self.span(),
opaque_span: self.tcx.def_span(alias_ty.def_id),
opaque_span: self.tcx.def_span(alias_ty.kind.def_id()),
});
}
}
@@ -203,21 +203,24 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
t.super_visit_with(self);
match *t.kind() {
ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
ty::Alias(alias_ty @ ty::AliasTy { kind: ty::Opaque { def_id }, .. })
if def_id.is_local() =>
{
self.visit_opaque_ty(alias_ty);
}
// Skips type aliases, as they are meant to be transparent.
// FIXME(type_alias_impl_trait): can we require mentioning nested type aliases explicitly?
ty::Alias(ty::Free, alias_ty) if let Some(def_id) = alias_ty.def_id.as_local() => {
ty::Alias(alias_ty @ ty::AliasTy { kind: ty::Free { def_id }, .. })
if let Some(def_id) = def_id.as_local() =>
{
if !self.seen.insert(def_id) {
return;
}
self.tcx
.type_of(alias_ty.def_id)
.instantiate(self.tcx, alias_ty.args)
.visit_with(self);
self.tcx.type_of(def_id).instantiate(self.tcx, alias_ty.args).visit_with(self);
}
ty::Alias(ty::Projection, alias_ty) => {
ty::Alias(
alias_ty @ ty::AliasTy { kind: ty::Projection { def_id: alias_def_id }, .. },
) => {
// This avoids having to do normalization of `Self::AssocTy` by only
// supporting the case of a method defining opaque types from assoc types
// in the same impl block.
@@ -229,7 +232,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
if alias_ty.trait_ref(self.tcx) == impl_trait_ref {
for &assoc in self.tcx.associated_items(parent).in_definition_order() {
trace!(?assoc);
if assoc.expect_trait_impl() != Ok(alias_ty.def_id) {
if assoc.expect_trait_impl() != Ok(alias_def_id) {
continue;
}
@@ -264,7 +267,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
}
}
} else if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
self.tcx.opt_rpitit_info(alias_ty.def_id)
self.tcx.opt_rpitit_info(alias_def_id)
&& fn_def_id == self.item.into()
{
// RPITIT in trait definitions get desugared to an associated type. For
@@ -278,8 +281,12 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
// `Projection(<Self as Trait>::synthetic_assoc_ty, trait_def::opaque)`
// assumption to the `param_env` of the default method. We also separately
// rely on that assumption here.
let ty = self.tcx.type_of(alias_ty.def_id).instantiate(self.tcx, alias_ty.args);
let ty::Alias(ty::Opaque, alias_ty) = *ty.kind() else { bug!("{ty:?}") };
let ty = self.tcx.type_of(alias_def_id).instantiate(self.tcx, alias_ty.args);
let ty::Alias(alias_ty @ ty::AliasTy { kind: ty::Opaque { .. }, .. }) =
*ty.kind()
else {
bug!("{ty:?}")
};
self.visit_opaque_ty(alias_ty);
}
}
+11 -6
View File
@@ -222,13 +222,18 @@ fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, binder: &ty::Binder<'
}
fn visit_ty(&mut self, ty: Ty<'tcx>) {
if let ty::Alias(ty::Projection, unshifted_alias_ty) = *ty.kind()
if let ty::Alias(
unshifted_alias_ty @ ty::AliasTy {
kind: ty::Projection { def_id: unshifted_alias_ty_def_id },
..
},
) = *ty.kind()
&& let Some(
ty::ImplTraitInTraitData::Trait { fn_def_id, .. }
| ty::ImplTraitInTraitData::Impl { fn_def_id, .. },
) = self.tcx.opt_rpitit_info(unshifted_alias_ty.def_id)
) = self.tcx.opt_rpitit_info(unshifted_alias_ty_def_id)
&& fn_def_id == self.fn_def_id
&& self.seen.insert(unshifted_alias_ty.def_id)
&& self.seen.insert(unshifted_alias_ty_def_id)
{
// We have entered some binders as we've walked into the
// bounds of the RPITIT. Shift these binders back out when
@@ -253,7 +258,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
// strategy, then just reinterpret the associated type like an opaque :^)
let default_ty = self
.tcx
.type_of(shifted_alias_ty.def_id)
.type_of(shifted_alias_ty.kind.def_id())
.instantiate(self.tcx, shifted_alias_ty.args);
self.predicates.push(
@@ -273,7 +278,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
// easier to just do this.
for bound in self
.tcx
.item_bounds(unshifted_alias_ty.def_id)
.item_bounds(unshifted_alias_ty_def_id)
.iter_instantiated(self.tcx, unshifted_alias_ty.args)
{
bound.visit_with(self);
@@ -387,7 +392,7 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId)
| ty::CoroutineWitness(_, _)
| ty::Never
| ty::Tuple(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Placeholder(_)
+7 -7
View File
@@ -290,15 +290,15 @@ fn add_kind(&mut self, kind: &ty::TyKind<I>) {
self.add_args(args.as_slice());
}
ty::Alias(kind, data) => {
self.add_flags(match kind {
ty::Projection => TypeFlags::HAS_TY_PROJECTION,
ty::Free => TypeFlags::HAS_TY_FREE_ALIAS,
ty::Opaque => TypeFlags::HAS_TY_OPAQUE,
ty::Inherent => TypeFlags::HAS_TY_INHERENT,
ty::Alias(alias) => {
self.add_flags(match alias.kind {
ty::Projection { .. } => TypeFlags::HAS_TY_PROJECTION,
ty::Free { .. } => TypeFlags::HAS_TY_FREE_ALIAS,
ty::Opaque { .. } => TypeFlags::HAS_TY_OPAQUE,
ty::Inherent { .. } => TypeFlags::HAS_TY_INHERENT,
});
self.add_alias_ty(data);
self.add_alias_ty(alias);
}
ty::Dynamic(obj, r) => {
+2 -2
View File
@@ -185,7 +185,7 @@ fn is_guaranteed_unsized_raw(self) -> bool {
| ty::CoroutineWitness(_, _)
| ty::Never
| ty::Tuple(_)
| ty::Alias(_, _)
| ty::Alias(_)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Placeholder(_)
@@ -390,7 +390,7 @@ fn is_error(self) -> bool {
fn to_alias_term(self) -> Option<ty::AliasTerm<I>> {
match self.kind() {
ty::TermKind::Ty(ty) => match ty.kind() {
ty::Alias(_kind, alias_ty) => Some(alias_ty.into()),
ty::Alias(alias_ty) => Some(alias_ty.into()),
_ => None,
},
ty::TermKind::Const(ct) => match ct.kind() {

Some files were not shown because too many files have changed in this diff Show More