mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
ty::Alias refactor: fixup all the compiler code
This commit is contained in:
@@ -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()
|
||||
};
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:?}`"),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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(_) => {
|
||||
|
||||
@@ -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, _) => {
|
||||
|
||||
@@ -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(_)
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(_)
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user