authorbors <bors@rust-lang.org> 2026-06-23 17:44:39 UTC
committerbors <bors@rust-lang.org> 2026-06-23 17:44:39 UTC
logf28ac764c36004fa6a6e098d15b4016a838c13c6
treec6df7081c940cba8b4289c531f37e5c9b5b81dbc
parent4429659e4745016bd3f26a4a421843edc7fbc422
parent992c2de84a5c80da85886246b3a2e57a2f8e7146

Auto merge of #158013 - khyperia:AliasTy-def_id, r=BoxyUwU

remove AliasTy::def_id() this is part of https://github.com/rust-lang/rust/issues/156181 as well as part of https://github.com/rust-lang/rust/issues/152245 this immediately uses [the recently-introduced `Alias<>` type](https://github.com/rust-lang/rust/pull/156538) to narrow the kinds of aliases allowed in various places in code fyi @lcnr r? @BoxyUwU

39 files changed, 386 insertions(+), 216 deletions(-)

compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs+18-17
......@@ -83,15 +83,15 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
8383
8484 for trait_projection in collector.types.into_iter().rev() {
8585 let impl_opaque_args = trait_projection.args.rebase_onto(tcx, trait_m.def_id, impl_m_args);
86 let hidden_ty = hidden_tys[&trait_projection.kind.def_id()]
87 .instantiate(tcx, impl_opaque_args)
88 .skip_norm_wip();
86 let hidden_ty =
87 hidden_tys[&trait_projection.kind].instantiate(tcx, impl_opaque_args).skip_norm_wip();
8988
9089 // If the hidden type is not an opaque, then we have "refined" the trait signature.
91 let ty::Alias(
92 impl_opaque @ ty::AliasTy { kind: ty::Opaque { def_id: impl_opaque_def_id }, .. },
93 ) = *hidden_ty.kind()
94 else {
90 let impl_opaque = if let ty::Alias(alias) = *hidden_ty.kind()
91 && let Some(impl_opaque) = alias.try_to_opaque()
92 {
93 impl_opaque
94 } else {
9595 report_mismatched_rpitit_signature(
9696 tcx,
9797 trait_m_sig_with_self_for_diag,
......@@ -105,7 +105,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
105105
106106 // This opaque also needs to be from the impl method -- otherwise,
107107 // it's a refinement to a TAIT.
108 if !tcx.hir_get_if_local(impl_opaque_def_id).is_some_and(|node| {
108 if !tcx.hir_get_if_local(impl_opaque.kind).is_some_and(|node| {
109109 matches!(
110110 node.expect_opaque_ty().origin,
111111 hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. }
......@@ -124,13 +124,13 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
124124 }
125125
126126 trait_bounds.extend(
127 tcx.item_bounds(trait_projection.kind.def_id())
127 tcx.item_bounds(trait_projection.kind)
128128 .iter_instantiated(tcx, trait_projection.args)
129129 .map(Unnormalized::skip_norm_wip),
130130 );
131131 impl_bounds.extend(elaborate(
132132 tcx,
133 tcx.explicit_item_bounds(impl_opaque_def_id)
133 tcx.explicit_item_bounds(impl_opaque.kind)
134134 .iter_instantiated_copied(tcx, impl_opaque.args)
135135 .map(Unnormalized::skip_norm_wip),
136136 ));
......@@ -231,7 +231,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
231231 // is literally unrepresentable in the type system; however, we may be
232232 // promising stronger outlives guarantees if we capture *fewer* regions.
233233 for (trait_projection, impl_opaque) in pairs {
234 let impl_variances = tcx.variances_of(impl_opaque.kind.def_id());
234 let impl_variances = tcx.variances_of(impl_opaque.kind);
235235 let impl_captures: FxIndexSet<_> = impl_opaque
236236 .args
237237 .iter()
......@@ -240,7 +240,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
240240 .map(|(arg, _)| arg)
241241 .collect();
242242
243 let trait_variances = tcx.variances_of(trait_projection.kind.def_id());
243 let trait_variances = tcx.variances_of(trait_projection.kind);
244244 let mut trait_captures = FxIndexSet::default();
245245 for (arg, variance) in trait_projection.args.iter().zip_eq(trait_variances) {
246246 if *variance != ty::Invariant {
......@@ -252,7 +252,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
252252 if !trait_captures.iter().all(|arg| impl_captures.contains(arg)) {
253253 report_mismatched_rpitit_captures(
254254 tcx,
255 impl_opaque.kind.def_id().expect_local(),
255 impl_opaque.kind.expect_local(),
256256 trait_captures,
257257 is_internal,
258258 );
......@@ -262,18 +262,19 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
262262
263263struct ImplTraitInTraitCollector<'tcx> {
264264 tcx: TyCtxt<'tcx>,
265 types: FxIndexSet<ty::AliasTy<'tcx>>,
265 types: FxIndexSet<ty::ProjectionAliasTy<'tcx>>,
266266}
267267
268268impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'tcx> {
269269 fn visit_ty(&mut self, ty: Ty<'tcx>) {
270 if let ty::Alias(proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. }) = *ty.kind()
271 && self.tcx.is_impl_trait_in_trait(def_id)
270 if let ty::Alias(alias) = *ty.kind()
271 && let Some(proj) = alias.try_to_projection()
272 && self.tcx.is_impl_trait_in_trait(proj.kind)
272273 {
273274 if self.types.insert(proj) {
274275 for (pred, _) in self
275276 .tcx
276 .explicit_item_bounds(def_id)
277 .explicit_item_bounds(proj.kind)
277278 .iter_instantiated_copied(self.tcx, proj.args)
278279 .map(Unnormalized::skip_norm_wip)
279280 {
compiler/rustc_hir_analysis/src/check/mod.rs+2-12
......@@ -89,7 +89,6 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
8989use rustc_middle::ty::print::with_types_for_signature;
9090use rustc_middle::ty::{
9191 self, GenericArgs, GenericArgsRef, OutlivesPredicate, Region, Ty, TyCtxt, TypingMode,
92 Unnormalized,
9392};
9493use rustc_middle::{bug, span_bug};
9594use rustc_session::errors::feature_err;
......@@ -487,21 +486,12 @@ fn fn_sig_suggestion<'tcx>(
487486 let mut output = sig.output();
488487
489488 let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
490 output = if let ty::Alias(alias_ty) = *output.kind()
491 && let Some(output) = tcx
492 .explicit_item_self_bounds(alias_ty.kind.def_id())
493 .iter_instantiated_copied(tcx, alias_ty.args)
494 .map(Unnormalized::skip_norm_wip)
495 .find_map(|(bound, _)| {
496 bound.as_projection_clause()?.no_bound_vars()?.term.as_type()
497 }) {
498 output
499 } else {
489 output = tcx.get_impl_future_output_ty(output).unwrap_or_else(|| {
500490 span_bug!(
501491 ident.span,
502492 "expected async fn to have `impl Future` output, but it returns {output}"
503493 )
504 };
494 });
505495 "async "
506496 } else {
507497 ""
compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs+5-1
......@@ -1356,7 +1356,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13561356 )? {
13571357 TypeRelativePath::AssocItem(alias_term) => {
13581358 let alias_ty = alias_term.expect_ty();
1359 let def_id = alias_ty.kind.def_id();
1359 let def_id = match alias_ty.kind {
1360 ty::AliasTyKind::Projection { def_id } => def_id,
1361 ty::AliasTyKind::Inherent { def_id } => def_id,
1362 kind => bug!("expected projection or inherent alias, got {kind:?}"),
1363 };
13601364 let ty = alias_ty.to_ty(tcx);
13611365 let ty = self.check_param_uses_if_mcg(ty, span, false);
13621366 Ok((ty, tcx.def_kind(def_id), def_id))
compiler/rustc_hir_typeck/src/expr.rs+1-1
......@@ -2910,7 +2910,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29102910 base: &'tcx hir::Expr<'tcx>,
29112911 ty: Ty<'tcx>,
29122912 ) {
2913 let Some(output_ty) = self.err_ctxt().get_impl_future_output_ty(ty) else {
2913 let Some(output_ty) = self.tcx.get_impl_future_output_ty(ty) else {
29142914 err.span_label(field_ident.span, "unknown field");
29152915 return;
29162916 };
compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs+1-1
......@@ -1351,7 +1351,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13511351 .instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars));
13521352 let ty = match self.tcx.asyncness(fn_id) {
13531353 ty::Asyncness::Yes => {
1354 self.err_ctxt().get_impl_future_output_ty(ty).unwrap_or_else(|| {
1354 self.tcx.get_impl_future_output_ty(ty).unwrap_or_else(|| {
13551355 span_bug!(
13561356 fn_decl.output.span(),
13571357 "failed to get output type of async function"
compiler/rustc_hir_typeck/src/method/suggest.rs+1-1
......@@ -3878,7 +3878,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38783878 span: Span,
38793879 return_type: Option<Ty<'tcx>>,
38803880 ) {
3881 let Some(output_ty) = self.err_ctxt().get_impl_future_output_ty(ty) else { return };
3881 let Some(output_ty) = self.tcx.get_impl_future_output_ty(ty) else { return };
38823882 let output_ty = self.resolve_vars_if_possible(output_ty);
38833883 let method_exists =
38843884 self.method_exists_for_diagnostic(item_name, output_ty, call.hir_id, return_type);
compiler/rustc_infer/src/infer/context.rs+1-1
......@@ -380,7 +380,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
380380 .map(|(k, h)| (k, h.ty))
381381 .collect()
382382 }
383 fn opaques_with_sub_unified_hidden_type(&self, ty: ty::TyVid) -> Vec<ty::AliasTy<'tcx>> {
383 fn opaques_with_sub_unified_hidden_type(&self, ty: ty::TyVid) -> Vec<ty::OpaqueAliasTy<'tcx>> {
384384 self.opaques_with_sub_unified_hidden_type(ty)
385385 }
386386
compiler/rustc_infer/src/infer/mod.rs+6-3
......@@ -1115,7 +1115,10 @@ impl<'tcx> InferCtxt<'tcx> {
11151115 /// Searches for an opaque type key whose hidden type is related to `ty_vid`.
11161116 ///
11171117 /// This only checks for a subtype relation, it does not require equality.
1118 pub fn opaques_with_sub_unified_hidden_type(&self, ty_vid: TyVid) -> Vec<ty::AliasTy<'tcx>> {
1118 pub fn opaques_with_sub_unified_hidden_type(
1119 &self,
1120 ty_vid: TyVid,
1121 ) -> Vec<ty::OpaqueAliasTy<'tcx>> {
11191122 // Avoid accidentally allowing more code to compile with the old solver.
11201123 if !self.next_trait_solver() {
11211124 return vec![];
......@@ -1133,9 +1136,9 @@ impl<'tcx> InferCtxt<'tcx> {
11331136 if let ty::Infer(ty::TyVar(hidden_vid)) = *hidden_ty.ty.kind() {
11341137 let opaque_sub_vid = type_variables.sub_unification_table_root_var(hidden_vid);
11351138 if opaque_sub_vid == ty_sub_vid {
1136 return Some(ty::AliasTy::new_from_args(
1139 return Some(ty::OpaqueAliasTy::new_opaque_from_args(
11371140 self.tcx,
1138 ty::Opaque { def_id: key.def_id.into() },
1141 key.def_id.into(),
11391142 key.args,
11401143 ));
11411144 }
compiler/rustc_infer/src/infer/outlives/for_liveness.rs+7-1
......@@ -59,8 +59,14 @@ where
5959 ty::Alias(ty::AliasTy { kind, args, .. }) => {
6060 let tcx = self.tcx;
6161 let param_env = self.param_env;
62 let def_id = match kind {
63 ty::AliasTyKind::Projection { def_id }
64 | ty::AliasTyKind::Inherent { def_id }
65 | ty::AliasTyKind::Opaque { def_id }
66 | ty::AliasTyKind::Free { def_id } => def_id,
67 };
6268 let outlives_bounds: Vec<_> = tcx
63 .item_bounds(kind.def_id())
69 .item_bounds(def_id)
6470 .iter_instantiated(tcx, args)
6571 .map(Unnormalized::skip_norm_wip)
6672 .chain(param_env.caller_bounds())
compiler/rustc_infer/src/infer/outlives/verify.rs+1-2
......@@ -236,8 +236,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
236236 // And therefore we can safely use structural equality for alias types.
237237 (GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {}
238238 (GenericKind::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => {}
239 (GenericKind::Alias(a1), ty::Alias(a2)) if a1.kind.def_id() == a2.kind.def_id() => {
240 }
239 (GenericKind::Alias(a1), ty::Alias(a2)) if a1.kind == a2.kind => {}
241240 _ => return None,
242241 }
243242
compiler/rustc_middle/src/query/keys.rs+6-1
......@@ -385,7 +385,12 @@ fn def_id_of_type_cached<'a>(ty: Ty<'a>, visited: &mut SsoHashSet<Ty<'a>>) -> Op
385385 | ty::CoroutineWitness(def_id, _)
386386 | ty::Foreign(def_id) => Some(def_id),
387387
388 ty::Alias(alias) => Some(alias.kind.def_id()),
388 ty::Alias(alias) => match alias.kind {
389 ty::AliasTyKind::Projection { def_id }
390 | ty::AliasTyKind::Inherent { def_id }
391 | ty::AliasTyKind::Opaque { def_id }
392 | ty::AliasTyKind::Free { def_id } => Some(def_id),
393 },
389394
390395 ty::Bool
391396 | ty::Char
compiler/rustc_middle/src/ty/context.rs+33
......@@ -2704,6 +2704,39 @@ impl<'tcx> TyCtxt<'tcx> {
27042704 self.opt_rpitit_info(def_id).is_some()
27052705 }
27062706
2707 pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2708 let (def_id, args) = match *ty.kind() {
2709 ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2710 ty::Alias(ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2711 if self.is_impl_trait_in_trait(def_id) =>
2712 {
2713 (def_id, args)
2714 }
2715 _ => return None,
2716 };
2717
2718 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2719 let item_def_id = self.associated_item_def_ids(future_trait)[0];
2720
2721 self.explicit_item_self_bounds(def_id)
2722 .iter_instantiated_copied(self, args)
2723 .map(ty::Unnormalized::skip_norm_wip)
2724 .find_map(|(predicate, _)| {
2725 predicate
2726 .kind()
2727 .map_bound(|kind| match kind {
2728 ty::ClauseKind::Projection(projection_predicate)
2729 if projection_predicate.def_id() == item_def_id =>
2730 {
2731 projection_predicate.term.as_type()
2732 }
2733 _ => None,
2734 })
2735 .no_bound_vars()
2736 .flatten()
2737 })
2738 }
2739
27072740 /// Named module children from all kinds of items, including imports.
27082741 /// In addition to regular items this list also includes struct and variant constructors, and
27092742 /// items inside `extern {}` blocks because all of them introduce names into parent module.
compiler/rustc_middle/src/ty/mod.rs+6-5
......@@ -104,11 +104,12 @@ pub use self::region::{
104104 EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region, RegionKind, RegionVid,
105105};
106106pub use self::sty::{
107 AliasTy, AliasTyKind, Article, Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy,
108 BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, CoroutineArgsExt, EarlyBinder, FnSig,
109 FnSigKind, InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PlaceholderConst,
110 PlaceholderRegion, PlaceholderType, PolyFnSig, TyKind, TypeAndMut, TypingMode,
111 TypingModeEqWrapper, Unnormalized, UpvarArgs,
107 Alias, AliasTy, AliasTyKind, Article, Binder, BoundConst, BoundRegion, BoundRegionKind,
108 BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, CoroutineArgsExt, EarlyBinder,
109 FnSig, FnSigKind, FreeAliasTy, InherentAliasTy, InlineConstArgs, InlineConstArgsParts,
110 OpaqueAliasTy, ParamConst, ParamTy, PlaceholderConst, PlaceholderRegion, PlaceholderType,
111 PolyFnSig, ProjectionAliasTy, TyKind, TypeAndMut, TypingMode, TypingModeEqWrapper,
112 Unnormalized, UpvarArgs,
112113};
113114pub use self::trait_def::TraitDef;
114115pub use self::typeck_results::{
compiler/rustc_middle/src/ty/print/pretty.rs+6-2
......@@ -1369,10 +1369,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
13691369 self.tcx().opt_rpitit_info(def_id)
13701370 && let ty::Alias(alias_ty) =
13711371 self.tcx().fn_sig(fn_def_id).skip_binder().output().skip_binder().kind()
1372 && alias_ty.kind.def_id() == def_id
1372 && let Some(projection_ty) = alias_ty.try_to_projection()
1373 && projection_ty.kind == def_id
13731374 && let generics = self.tcx().generics_of(fn_def_id)
13741375 // FIXME(return_type_notation): We only support lifetime params for now.
1375 && generics.own_params.iter().all(|param| matches!(param.kind, ty::GenericParamDefKind::Lifetime))
1376 && generics
1377 .own_params
1378 .iter()
1379 .all(|param| matches!(param.kind, ty::GenericParamDefKind::Lifetime))
13761380 {
13771381 let num_args = generics.count();
13781382 Some((fn_def_id, &args[..num_args]))
compiler/rustc_middle/src/ty/sty.rs+21-6
......@@ -38,6 +38,11 @@ pub type TyKind<'tcx> = ir::TyKind<TyCtxt<'tcx>>;
3838pub type TypeAndMut<'tcx> = ir::TypeAndMut<TyCtxt<'tcx>>;
3939pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>;
4040pub type AliasTyKind<'tcx> = ir::AliasTyKind<TyCtxt<'tcx>>;
41pub type Alias<'tcx, K> = ir::Alias<TyCtxt<'tcx>, K>;
42pub type ProjectionAliasTy<'tcx> = ir::ProjectionAliasTy<TyCtxt<'tcx>>;
43pub type InherentAliasTy<'tcx> = ir::InherentAliasTy<TyCtxt<'tcx>>;
44pub type OpaqueAliasTy<'tcx> = ir::OpaqueAliasTy<TyCtxt<'tcx>>;
45pub type FreeAliasTy<'tcx> = ir::FreeAliasTy<TyCtxt<'tcx>>;
4146pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>;
4247pub type FnSigKind<'tcx> = ir::FnSigKind<TyCtxt<'tcx>>;
4348pub type Binder<'tcx, T> = ir::Binder<TyCtxt<'tcx>, T>;
......@@ -477,12 +482,22 @@ impl<'tcx> Ty<'tcx> {
477482
478483 #[inline]
479484 pub fn new_alias(tcx: TyCtxt<'tcx>, alias_ty: ty::AliasTy<'tcx>) -> Ty<'tcx> {
480 debug_assert_matches!(
481 (alias_ty.kind, tcx.def_kind(alias_ty.kind.def_id())),
482 (ty::Opaque { .. }, DefKind::OpaqueTy)
483 | (ty::Projection { .. } | ty::Inherent { .. }, DefKind::AssocTy)
484 | (ty::Free { .. }, DefKind::TyAlias)
485 );
485 if cfg!(debug_assertions) {
486 match alias_ty.kind {
487 ty::AliasTyKind::Projection { def_id } => {
488 debug_assert_matches!(tcx.def_kind(def_id), DefKind::AssocTy)
489 }
490 ty::AliasTyKind::Inherent { def_id } => {
491 debug_assert_matches!(tcx.def_kind(def_id), DefKind::AssocTy)
492 }
493 ty::AliasTyKind::Opaque { def_id } => {
494 debug_assert_matches!(tcx.def_kind(def_id), DefKind::OpaqueTy)
495 }
496 ty::AliasTyKind::Free { def_id } => {
497 debug_assert_matches!(tcx.def_kind(def_id), DefKind::TyAlias)
498 }
499 }
500 }
486501 Ty::new(tcx, Alias(alias_ty))
487502 }
488503
compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs+22-17
......@@ -741,7 +741,7 @@ where
741741 candidates: &mut Vec<Candidate<I>>,
742742 consider_self_bounds: AliasBoundKind,
743743 ) -> Result<(), RerunNonErased> {
744 let alias_ty = match self_ty.kind() {
744 let (alias_ty, def_id) = match self_ty.kind() {
745745 ty::Bool
746746 | ty::Char
747747 | ty::Int(_)
......@@ -789,9 +789,12 @@ where
789789 return Ok(());
790790 }
791791
792 ty::Alias(
793 alias_ty @ AliasTy { kind: ty::Projection { .. } | ty::Opaque { .. }, .. },
794 ) => alias_ty,
792 ty::Alias(alias_ty @ AliasTy { kind: ty::Projection { def_id }, .. }) => {
793 (alias_ty, def_id.into())
794 }
795 ty::Alias(alias_ty @ AliasTy { kind: ty::Opaque { def_id }, .. }) => {
796 (alias_ty, def_id.into())
797 }
795798 ty::Alias(AliasTy { kind: ty::Inherent { .. } | ty::Free { .. }, .. }) => {
796799 self.cx().delay_bug(format!("could not normalize {self_ty:?}, it is not WF"));
797800 return Ok(());
......@@ -802,7 +805,7 @@ where
802805 AliasBoundKind::SelfBounds => {
803806 for assumption in self
804807 .cx()
805 .item_self_bounds(alias_ty.kind.def_id())
808 .item_self_bounds(def_id)
806809 .iter_instantiated(self.cx(), alias_ty.args)
807810 .map(Unnormalized::skip_norm_wip)
808811 {
......@@ -818,7 +821,7 @@ where
818821 AliasBoundKind::NonSelfBounds => {
819822 for assumption in self
820823 .cx()
821 .item_non_self_bounds(alias_ty.kind.def_id())
824 .item_non_self_bounds(def_id)
822825 .iter_instantiated(self.cx(), alias_ty.args)
823826 .map(Unnormalized::skip_norm_wip)
824827 {
......@@ -835,12 +838,12 @@ where
835838
836839 candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty));
837840
838 if !matches!(alias_ty.kind, ty::Projection { .. }) {
841 let Some(projection_ty) = alias_ty.try_to_projection() else {
839842 return Ok(());
840 }
843 };
841844
842845 // Recurse on the self type of the projection.
843 match self.structurally_normalize_ty(goal.param_env, alias_ty.self_ty()) {
846 match self.structurally_normalize_ty(goal.param_env, projection_ty.projection_self_ty()) {
844847 Ok(next_self_ty) => self.assemble_alias_bound_candidates_recur(
845848 next_self_ty,
846849 goal,
......@@ -1072,12 +1075,12 @@ where
10721075 return Ok(());
10731076 }
10741077
1075 for &alias_ty in &opaque_types {
1076 debug!("self ty is sub unified with {alias_ty:?}");
1078 for &opaque_ty in &opaque_types {
1079 debug!("self ty is sub unified with {opaque_ty:?}");
10771080
10781081 struct ReplaceOpaque<I: Interner> {
10791082 cx: I,
1080 alias_ty: ty::AliasTy<I>,
1083 opaque_ty: ty::OpaqueAliasTy<I>,
10811084 self_ty: I::Ty,
10821085 }
10831086 impl<I: Interner> TypeFolder<I> for ReplaceOpaque<I> {
......@@ -1085,8 +1088,10 @@ where
10851088 self.cx
10861089 }
10871090 fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
1088 if let ty::Alias(alias_ty) = ty.kind() {
1089 if alias_ty == self.alias_ty {
1091 if let ty::Alias(alias_ty) = ty.kind()
1092 && let Some(opaque_ty) = alias_ty.try_to_opaque()
1093 {
1094 if opaque_ty == self.opaque_ty {
10901095 return self.self_ty;
10911096 }
10921097 }
......@@ -1103,12 +1108,12 @@ where
11031108 // in a `?x: Trait<u32>` alias-bound candidate.
11041109 for item_bound in self
11051110 .cx()
1106 .item_self_bounds(alias_ty.kind.def_id())
1107 .iter_instantiated(self.cx(), alias_ty.args)
1111 .item_self_bounds(opaque_ty.kind.into())
1112 .iter_instantiated(self.cx(), opaque_ty.args)
11081113 .map(Unnormalized::skip_norm_wip)
11091114 {
11101115 let assumption =
1111 item_bound.fold_with(&mut ReplaceOpaque { cx: self.cx(), alias_ty, self_ty });
1116 item_bound.fold_with(&mut ReplaceOpaque { cx: self.cx(), opaque_ty, self_ty });
11121117 candidates.extend(G::probe_and_match_goal_against_assumption(
11131118 self,
11141119 CandidateSource::AliasBound(AliasBoundKind::SelfBounds),
compiler/rustc_next_trait_solver/src/solve/effect_goals.rs+16-9
......@@ -86,17 +86,24 @@ where
8686 let cx = ecx.cx();
8787 let mut candidates = vec![];
8888
89 if !ecx.cx().alias_has_const_conditions(alias_ty.kind.def_id()) {
89 let def_id = match alias_ty.kind {
90 ty::AliasTyKind::Projection { def_id } => def_id.into(),
91 ty::AliasTyKind::Inherent { def_id } => def_id.into(),
92 ty::AliasTyKind::Opaque { def_id } => def_id.into(),
93 ty::AliasTyKind::Free { def_id } => def_id.into(),
94 };
95
96 if !ecx.cx().alias_has_const_conditions(def_id) {
9097 return vec![];
9198 }
9299
93100 for clause in elaborate::elaborate(
94101 cx,
95 cx.explicit_implied_const_bounds(alias_ty.kind.def_id())
96 .iter_instantiated(cx, alias_ty.args)
97 .map(|trait_ref| {
102 cx.explicit_implied_const_bounds(def_id).iter_instantiated(cx, alias_ty.args).map(
103 |trait_ref| {
98104 trait_ref.to_host_effect_clause(cx, goal.predicate.constness).skip_norm_wip()
99 }),
105 },
106 ),
100107 ) {
101108 candidates.extend(Self::probe_and_match_goal_against_assumption(
102109 ecx,
......@@ -107,16 +114,16 @@ where
107114 // Const conditions must hold for the implied const bound to hold.
108115 ecx.add_goals(
109116 GoalSource::AliasBoundConstCondition,
110 cx.const_conditions(alias_ty.kind.def_id())
111 .iter_instantiated(cx, alias_ty.args)
112 .map(|trait_ref| {
117 cx.const_conditions(def_id).iter_instantiated(cx, alias_ty.args).map(
118 |trait_ref| {
113119 goal.with(
114120 cx,
115121 trait_ref
116122 .to_host_effect_clause(cx, goal.predicate.constness)
117123 .skip_norm_wip(),
118124 )
119 }),
125 },
126 ),
120127 );
121128 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
122129 },
compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs+1-1
......@@ -1588,7 +1588,7 @@ where
15881588 pub(crate) fn opaques_with_sub_unified_hidden_type(
15891589 &self,
15901590 self_ty: I::Ty,
1591 ) -> Vec<ty::AliasTy<I>> {
1591 ) -> Vec<ty::OpaqueAliasTy<I>> {
15921592 if let ty::Infer(ty::TyVar(vid)) = self_ty.kind() {
15931593 self.delegate.opaques_with_sub_unified_hidden_type(vid)
15941594 } else {
compiler/rustc_public/src/unstable/convert/stable/ty.rs+8-4
......@@ -32,10 +32,14 @@ impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> {
3232 cx: &CompilerCtxt<'cx, BridgeTys>,
3333 ) -> Self::T {
3434 let ty::AliasTy { args, kind, .. } = self;
35 crate::ty::AliasTy {
36 def_id: tables.alias_def(kind.def_id()),
37 args: args.stable(tables, cx),
38 }
35 // rustc_public must change its API once we introduce a variant without a def_id.
36 let def_id = match *kind {
37 ty::AliasTyKind::Projection { def_id }
38 | ty::AliasTyKind::Inherent { def_id }
39 | ty::AliasTyKind::Opaque { def_id }
40 | ty::AliasTyKind::Free { def_id } => def_id,
41 };
42 crate::ty::AliasTy { def_id: tables.alias_def(def_id), args: args.stable(tables, cx) }
3943 }
4044}
4145
compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs-35
......@@ -56,7 +56,6 @@ use rustc_errors::{Applicability, Diag, DiagStyledString, IntoDiagArg, StringPar
5656use rustc_hir::attrs::diagnostic::{CustomDiagnostic, Directive, FormatArgs};
5757use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
5858use rustc_hir::intravisit::Visitor;
59use rustc_hir::lang_items::LangItem;
6059use rustc_hir::{self as hir, find_attr};
6160use rustc_infer::infer::DefineOpaqueTypes;
6261use rustc_macros::extension;
......@@ -207,40 +206,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
207206 )
208207 }
209208
210 pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
211 let (def_id, args) = match *ty.kind() {
212 ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
213 ty::Alias(ty::AliasTy { kind, args, .. })
214 if self.tcx.is_impl_trait_in_trait(kind.def_id()) =>
215 {
216 (kind.def_id(), args)
217 }
218 _ => return None,
219 };
220
221 let future_trait = self.tcx.require_lang_item(LangItem::Future, DUMMY_SP);
222 let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
223
224 self.tcx
225 .explicit_item_self_bounds(def_id)
226 .iter_instantiated_copied(self.tcx, args)
227 .map(Unnormalized::skip_norm_wip)
228 .find_map(|(predicate, _)| {
229 predicate
230 .kind()
231 .map_bound(|kind| match kind {
232 ty::ClauseKind::Projection(projection_predicate)
233 if projection_predicate.def_id() == item_def_id =>
234 {
235 projection_predicate.term.as_type()
236 }
237 _ => None,
238 })
239 .no_bound_vars()
240 .flatten()
241 })
242 }
243
244209 /// Adds a note if the types come from similarly named crates
245210 fn check_and_note_conflicting_crates(&self, err: &mut Diag<'_>, terr: TypeError<'tcx>) -> bool {
246211 match terr {
compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs+4-3
......@@ -126,12 +126,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
126126 region_def_id: DefId,
127127 hir_sig: &hir::FnSig<'_>,
128128 ) -> Option<Span> {
129 let fn_ty = self.tcx().type_of(scope_def_id).instantiate_identity().skip_norm_wip();
129 let tcx = self.tcx();
130 let fn_ty = tcx.type_of(scope_def_id).instantiate_identity().skip_norm_wip();
130131 if let ty::FnDef(_, _) = fn_ty.kind() {
131 let ret_ty = fn_ty.fn_sig(self.tcx()).output();
132 let ret_ty = fn_ty.fn_sig(tcx).output();
132133 let span = hir_sig.decl.output.span();
133134 let future_output = if hir_sig.header.is_async() {
134 ret_ty.map_bound(|ty| self.cx.get_impl_future_output_ty(ty)).transpose()
135 ret_ty.map_bound(|ty| tcx.get_impl_future_output_ty(ty)).transpose()
135136 } else {
136137 None
137138 };
compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs+18-10
......@@ -627,19 +627,19 @@ impl<T> Trait<T> for X {
627627 diag: &mut Diag<'_>,
628628 msg: impl Fn() -> String,
629629 body_owner_def_id: Option<DefId>,
630 proj_ty: ty::AliasTy<'tcx>,
630 alias_ty: ty::AliasTy<'tcx>,
631631 ty: Ty<'tcx>,
632632 ) -> bool {
633633 let tcx = self.tcx;
634634 // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
635 if !matches!(proj_ty.kind, ty::AliasTyKind::Projection { .. }) {
635 let Some(proj_ty) = alias_ty.try_to_projection() else {
636636 return false;
637 }
637 };
638638 let Some(body_owner_def_id) = body_owner_def_id else {
639639 return false;
640640 };
641 let assoc = tcx.associated_item(proj_ty.kind.def_id());
642 let (trait_ref, assoc_args) = proj_ty.trait_ref_and_own_args(tcx);
641 let assoc = tcx.associated_item(proj_ty.kind);
642 let (trait_ref, assoc_args) = alias_ty.trait_ref_and_own_args(tcx);
643643 let Some(item) = tcx.hir_get_if_local(body_owner_def_id) else {
644644 return false;
645645 };
......@@ -648,7 +648,7 @@ impl<T> Trait<T> for X {
648648 };
649649 // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
650650 // This will also work for `impl Trait`.
651 let ty::Param(param_ty) = *proj_ty.self_ty().kind() else {
651 let ty::Param(param_ty) = *alias_ty.self_ty().kind() else {
652652 return false;
653653 };
654654 let generics = tcx.generics_of(body_owner_def_id);
......@@ -684,7 +684,7 @@ impl<T> Trait<T> for X {
684684 _ => return false,
685685 };
686686 let parent = tcx.hir_get_parent_item(hir_id).def_id;
687 self.suggest_constraint(diag, msg, Some(parent.into()), proj_ty, ty)
687 self.suggest_constraint(diag, msg, Some(parent.into()), alias_ty, ty)
688688 }
689689
690690 /// An associated type was expected and a different type was found.
......@@ -719,6 +719,10 @@ impl<T> Trait<T> for X {
719719 return;
720720 }
721721
722 let (ty::Projection { def_id } | ty::Inherent { def_id }) = proj_ty.kind else {
723 panic!("expected projection or inherent alias, found {:?}", proj_ty.kind);
724 };
725
722726 let msg = || {
723727 format!(
724728 "consider constraining the associated type `{}` to `{}`",
......@@ -746,9 +750,9 @@ impl<T> Trait<T> for X {
746750 let point_at_assoc_fn = if callable_scope
747751 && self.point_at_methods_that_satisfy_associated_type(
748752 diag,
749 tcx.parent(proj_ty.kind.def_id()),
753 tcx.parent(def_id),
750754 current_method_ident,
751 proj_ty.kind.def_id(),
755 def_id,
752756 values.expected,
753757 ) {
754758 // If we find a suitable associated function that returns the expected type, we
......@@ -821,7 +825,11 @@ fn foo(&self) -> Self::T { String::new() }
821825 ) -> bool {
822826 let tcx = self.tcx;
823827
824 let assoc = tcx.associated_item(proj_ty.kind.def_id());
828 let (ty::Projection { def_id } | ty::Inherent { def_id }) = proj_ty.kind else {
829 panic!("expected projection or inherent alias, found {:?}", proj_ty.kind);
830 };
831
832 let assoc = tcx.associated_item(def_id);
825833 if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) =
826834 *proj_ty.self_ty().kind()
827835 {
compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs+2-2
......@@ -190,8 +190,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
190190 }
191191
192192 let subdiag = match (
193 self.get_impl_future_output_ty(exp_found.expected),
194 self.get_impl_future_output_ty(exp_found.found),
193 self.tcx.get_impl_future_output_ty(exp_found.expected),
194 self.tcx.get_impl_future_output_ty(exp_found.found),
195195 ) {
196196 (Some(exp), Some(found)) if self.same_type_modulo_infer(exp, found) => match cause
197197 .code()
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs+10-9
......@@ -128,7 +128,7 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
128128 msg: &str,
129129 err: &mut Diag<'_, G>,
130130 fn_sig: Option<&hir::FnSig<'_>>,
131 projection: Option<ty::AliasTy<'_>>,
131 projection: Option<ty::ProjectionAliasTy<'_>>,
132132 trait_pred: ty::PolyTraitPredicate<'tcx>,
133133 // When we are dealing with a trait, `super_traits` will be `Some`:
134134 // Given `trait T: A + B + C {}`
......@@ -140,11 +140,8 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
140140 if hir_generics.where_clause_span.from_expansion()
141141 || hir_generics.where_clause_span.desugaring_kind().is_some()
142142 || projection.is_some_and(|projection| {
143 (tcx.is_impl_trait_in_trait(projection.kind.def_id())
144 && !tcx.features().return_type_notation())
145 || tcx
146 .lookup_stability(projection.kind.def_id())
147 .is_some_and(|stab| stab.is_unstable())
143 (tcx.is_impl_trait_in_trait(projection.kind) && !tcx.features().return_type_notation())
144 || tcx.lookup_stability(projection.kind).is_some_and(|stab| stab.is_unstable())
148145 })
149146 {
150147 return;
......@@ -152,7 +149,7 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
152149 let generics = tcx.generics_of(item_id);
153150 // Given `fn foo(t: impl Trait)` where `Trait` requires assoc type `A`...
154151 if let Some((param, bound_str, fn_sig)) =
155 fn_sig.zip(projection).and_then(|(sig, p)| match *p.self_ty().kind() {
152 fn_sig.zip(projection).and_then(|(sig, p)| match *p.projection_self_ty().kind() {
156153 // Shenanigans to get the `Trait` from the `impl Trait`.
157154 ty::Param(param) => {
158155 let param_def = generics.type_param(param, tcx);
......@@ -479,8 +476,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
479476 let self_ty = trait_pred.skip_binder().self_ty();
480477 let (param_ty, projection) = match *self_ty.kind() {
481478 ty::Param(_) => (true, None),
482 ty::Alias(projection @ ty::AliasTy { kind: ty::Projection { .. }, .. }) => {
483 (false, Some(projection))
479 ty::Alias(alias) => {
480 if let Some(projection) = alias.try_to_projection() {
481 (false, Some(projection))
482 } else {
483 (false, None)
484 }
484485 }
485486 _ => (false, None),
486487 };
compiler/rustc_trait_selection/src/traits/effects.rs+3-4
......@@ -218,7 +218,7 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>(
218218 if candidate.is_some() {
219219 return Err(EvaluationFailure::Ambiguous);
220220 } else {
221 candidate = Some((data, alias_ty));
221 candidate = Some((data, alias_ty, def_id));
222222 }
223223 }
224224 }
......@@ -231,12 +231,11 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>(
231231 consider_ty = alias_ty.self_ty();
232232 }
233233
234 if let Some((data, alias_ty)) = candidate {
234 if let Some((data, alias_ty, def_id)) = candidate {
235235 Ok(match_candidate(selcx, obligation, data, true, |selcx, nested| {
236236 // An alias bound only holds if we also check the const conditions
237237 // of the alias, so we need to register those, too.
238 let const_conditions =
239 tcx.const_conditions(alias_ty.kind.def_id()).instantiate(tcx, alias_ty.args);
238 let const_conditions = tcx.const_conditions(def_id).instantiate(tcx, alias_ty.args);
240239 let const_conditions: Vec<_> = const_conditions
241240 .into_iter()
242241 .map(|(trait_ref, span)| {
compiler/rustc_ty_utils/src/ty.rs+7-11
......@@ -223,18 +223,14 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
223223 }
224224
225225 fn visit_ty(&mut self, ty: Ty<'tcx>) {
226 if let ty::Alias(
227 unshifted_alias_ty @ ty::AliasTy {
228 kind: ty::Projection { def_id: unshifted_alias_ty_def_id },
229 ..
230 },
231 ) = *ty.kind()
226 if let ty::Alias(unshifted_alias_ty) = *ty.kind()
227 && let Some(unshifted_alias_ty) = unshifted_alias_ty.try_to_projection()
232228 && let Some(
233229 ty::ImplTraitInTraitData::Trait { fn_def_id, .. }
234230 | ty::ImplTraitInTraitData::Impl { fn_def_id, .. },
235 ) = self.tcx.opt_rpitit_info(unshifted_alias_ty_def_id)
231 ) = self.tcx.opt_rpitit_info(unshifted_alias_ty.kind)
236232 && fn_def_id == self.fn_def_id
237 && self.seen.insert(unshifted_alias_ty_def_id)
233 && self.seen.insert(unshifted_alias_ty.kind)
238234 {
239235 // We have entered some binders as we've walked into the
240236 // bounds of the RPITIT. Shift these binders back out when
......@@ -259,14 +255,14 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
259255 // strategy, then just reinterpret the associated type like an opaque :^)
260256 let default_ty = self
261257 .tcx
262 .type_of(shifted_alias_ty.kind.def_id())
258 .type_of(shifted_alias_ty.kind)
263259 .instantiate(self.tcx, shifted_alias_ty.args)
264260 .skip_norm_wip();
265261
266262 self.predicates.push(
267263 ty::Binder::bind_with_vars(
268264 ty::ProjectionPredicate {
269 projection_term: shifted_alias_ty.into(),
265 projection_term: shifted_alias_ty.projection_to_alias_ty().into(),
270266 term: default_ty.into(),
271267 },
272268 self.bound_vars,
......@@ -280,7 +276,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
280276 // easier to just do this.
281277 for bound in self
282278 .tcx
283 .item_bounds(unshifted_alias_ty_def_id)
279 .item_bounds(unshifted_alias_ty.kind)
284280 .iter_instantiated(self.tcx, unshifted_alias_ty.args)
285281 .map(Unnormalized::skip_norm_wip)
286282 {
compiler/rustc_type_ir/src/infer_ctxt.rs+4-1
......@@ -502,7 +502,10 @@ pub trait InferCtxtLike: Sized {
502502 &self,
503503 prev_entries: Self::OpaqueTypeStorageEntries,
504504 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
505 fn opaques_with_sub_unified_hidden_type(&self, ty: TyVid) -> Vec<ty::AliasTy<Self::Interner>>;
505 fn opaques_with_sub_unified_hidden_type(
506 &self,
507 ty: TyVid,
508 ) -> Vec<ty::OpaqueAliasTy<Self::Interner>>;
506509
507510 fn register_hidden_type_in_storage(
508511 &self,
compiler/rustc_type_ir/src/lib.rs+1-1
......@@ -81,7 +81,7 @@ pub use predicate_kind::*;
8181pub use region_kind::*;
8282pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
8383use rustc_type_ir_macros::GenericTypeVisitable;
84pub use ty::{Alias, AliasTerm, AliasTy, UnevaluatedConst};
84pub use ty::{Alias, *};
8585pub use ty_info::*;
8686pub use ty_kind::*;
8787pub use unnormalized::Unnormalized;
compiler/rustc_type_ir/src/outlives.rs+8-1
......@@ -264,7 +264,14 @@ pub fn declared_bounds_from_definition<I: Interner>(
264264 cx: I,
265265 alias_ty: AliasTy<I>,
266266) -> impl Iterator<Item = I::Region> {
267 let bounds = cx.item_self_bounds(alias_ty.kind.def_id());
267 let def_id = match alias_ty.kind {
268 ty::AliasTyKind::Projection { def_id } => def_id.into(),
269 ty::AliasTyKind::Inherent { def_id } => def_id.into(),
270 ty::AliasTyKind::Opaque { def_id } => def_id.into(),
271 ty::AliasTyKind::Free { def_id } => def_id.into(),
272 };
273
274 let bounds = cx.item_self_bounds(def_id);
268275 bounds
269276 .iter_instantiated(cx, alias_ty.args)
270277 .map(Unnormalized::skip_norm_wip)
compiler/rustc_type_ir/src/relate.rs+1-1
......@@ -213,7 +213,7 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
213213 a: ty::AliasTy<I>,
214214 b: ty::AliasTy<I>,
215215 ) -> RelateResult<I, ty::AliasTy<I>> {
216 if a.kind.def_id() != b.kind.def_id() {
216 if a.kind != b.kind {
217217 Err(TypeError::ProjectionMismatched(ExpectedFound::new(a.kind.into(), b.kind.into())))
218218 } else {
219219 let cx = relation.cx();
compiler/rustc_type_ir/src/ty/alias.rs+4
......@@ -53,4 +53,8 @@ impl<I: Interner, K: Copy> Alias<I, K> {
5353
5454pub type AliasTerm<I> = Alias<I, AliasTermKind<I>>;
5555pub type AliasTy<I> = Alias<I, AliasTyKind<I>>;
56pub type ProjectionAliasTy<I> = Alias<I, <I as Interner>::TraitAssocTyId>;
57pub type InherentAliasTy<I> = Alias<I, <I as Interner>::InherentAssocTyId>;
58pub type OpaqueAliasTy<I> = Alias<I, <I as Interner>::OpaqueTyId>;
59pub type FreeAliasTy<I> = Alias<I, <I as Interner>::FreeTyAliasId>;
5660pub type UnevaluatedConst<I> = Alias<I, UnevaluatedConstKind<I>>;
compiler/rustc_type_ir/src/ty/mod.rs+1-1
......@@ -1,3 +1,3 @@
11mod alias;
22
3pub use alias::{Alias, AliasTerm, AliasTy, UnevaluatedConst};
3pub use alias::*;
compiler/rustc_type_ir/src/ty_kind.rs+144-7
......@@ -20,7 +20,10 @@ use crate::inherent::*;
2020use crate::ty::AliasTy;
2121#[cfg(feature = "nightly")]
2222use crate::visit::TypeVisitable;
23use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy};
23use crate::{
24 self as ty, BoundVarIndexKind, FloatTy, FreeAliasTy, InherentAliasTy, IntTy, Interner,
25 OpaqueAliasTy, ProjectionAliasTy, UintTy,
26};
2427
2528mod closure;
2629
......@@ -75,12 +78,31 @@ impl<I: Interner> AliasTyKind<I> {
7578 }
7679 }
7780
78 pub fn def_id(self) -> I::DefId {
81 pub fn try_to_projection(self) -> Option<I::TraitAssocTyId> {
82 match self {
83 AliasTyKind::Projection { def_id } => Some(def_id),
84 _ => None,
85 }
86 }
87
88 pub fn try_to_inherent(self) -> Option<I::InherentAssocTyId> {
89 match self {
90 AliasTyKind::Inherent { def_id } => Some(def_id),
91 _ => None,
92 }
93 }
94
95 pub fn try_to_opaque(self) -> Option<I::OpaqueTyId> {
96 match self {
97 AliasTyKind::Opaque { def_id } => Some(def_id),
98 _ => None,
99 }
100 }
101
102 pub fn try_to_free(self) -> Option<I::FreeTyAliasId> {
79103 match self {
80 AliasTyKind::Projection { def_id } => def_id.into(),
81 AliasTyKind::Inherent { def_id } => def_id.into(),
82 AliasTyKind::Opaque { def_id } => def_id.into(),
83 AliasTyKind::Free { def_id } => def_id.into(),
104 AliasTyKind::Free { def_id } => Some(def_id),
105 _ => None,
84106 }
85107 }
86108}
......@@ -430,7 +452,15 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
430452
431453impl<I: Interner> AliasTy<I> {
432454 pub fn new_from_args(interner: I, kind: AliasTyKind<I>, args: I::GenericArgs) -> AliasTy<I> {
433 interner.debug_assert_args_compatible(kind.def_id(), args);
455 if cfg!(debug_assertions) {
456 let def_id = match kind {
457 AliasTyKind::Projection { def_id } => def_id.into(),
458 AliasTyKind::Inherent { def_id } => def_id.into(),
459 AliasTyKind::Opaque { def_id } => def_id.into(),
460 AliasTyKind::Free { def_id } => def_id.into(),
461 };
462 interner.debug_assert_args_compatible(def_id, args);
463 }
434464 AliasTy { kind, args, _use_alias_new_instead: () }
435465 }
436466
......@@ -451,9 +481,67 @@ impl<I: Interner> AliasTy<I> {
451481 pub fn to_ty(self, interner: I) -> I::Ty {
452482 Ty::new_alias(interner, self)
453483 }
484
485 pub fn try_to_projection(self) -> Option<ProjectionAliasTy<I>> {
486 self.kind.try_to_projection().map(|kind| ty::Alias {
487 kind,
488 args: self.args,
489 _use_alias_new_instead: (),
490 })
491 }
492
493 pub fn try_to_inherent(self) -> Option<InherentAliasTy<I>> {
494 self.kind.try_to_inherent().map(|kind| ty::Alias {
495 kind,
496 args: self.args,
497 _use_alias_new_instead: (),
498 })
499 }
500
501 pub fn try_to_opaque(self) -> Option<OpaqueAliasTy<I>> {
502 self.kind.try_to_opaque().map(|kind| ty::Alias {
503 kind,
504 args: self.args,
505 _use_alias_new_instead: (),
506 })
507 }
508
509 pub fn try_to_free(self) -> Option<FreeAliasTy<I>> {
510 self.kind.try_to_free().map(|kind| ty::Alias {
511 kind,
512 args: self.args,
513 _use_alias_new_instead: (),
514 })
515 }
516}
517
518impl<I: Interner> ProjectionAliasTy<I> {
519 pub fn new_projection_from_args(
520 interner: I,
521 kind: I::TraitAssocTyId,
522 args: I::GenericArgs,
523 ) -> Self {
524 interner.debug_assert_args_compatible(kind.into(), args);
525 Self { kind, args, _use_alias_new_instead: () }
526 }
527
528 pub fn projection_to_alias_ty(self) -> AliasTy<I> {
529 AliasTy {
530 kind: AliasTyKind::Projection { def_id: self.kind },
531 args: self.args,
532 _use_alias_new_instead: (),
533 }
534 }
535
536 #[track_caller]
537 pub fn projection_self_ty(self) -> I::Ty {
538 self.args.type_at(0)
539 }
454540}
455541
456542/// The following methods work only with (trait) associated type projections.
543// FIXME: Migrate these to the impl on ProjectionAliasTy (by making callers use `try_to_projection`
544// or similar when they guard for projections)
457545impl<I: Interner> AliasTy<I> {
458546 #[track_caller]
459547 pub fn self_ty(self) -> I::Ty {
......@@ -498,6 +586,55 @@ impl<I: Interner> AliasTy<I> {
498586 }
499587}
500588
589impl<I: Interner> InherentAliasTy<I> {
590 pub fn new_inherent_from_args(
591 interner: I,
592 kind: I::InherentAssocTyId,
593 args: I::GenericArgs,
594 ) -> Self {
595 interner.debug_assert_args_compatible(kind.into(), args);
596 Self { kind, args, _use_alias_new_instead: () }
597 }
598
599 pub fn inherent_to_alias_ty(self) -> AliasTy<I> {
600 AliasTy {
601 kind: AliasTyKind::Inherent { def_id: self.kind },
602 args: self.args,
603 _use_alias_new_instead: (),
604 }
605 }
606}
607
608impl<I: Interner> OpaqueAliasTy<I> {
609 pub fn new_opaque_from_args(interner: I, kind: I::OpaqueTyId, args: I::GenericArgs) -> Self {
610 interner.debug_assert_args_compatible(kind.into(), args);
611 Self { kind, args, _use_alias_new_instead: () }
612 }
613
614 pub fn opaque_to_alias_ty(self) -> AliasTy<I> {
615 AliasTy {
616 kind: AliasTyKind::Opaque { def_id: self.kind },
617 args: self.args,
618 _use_alias_new_instead: (),
619 }
620 }
621}
622
623impl<I: Interner> FreeAliasTy<I> {
624 pub fn new_free_from_args(interner: I, kind: I::FreeTyAliasId, args: I::GenericArgs) -> Self {
625 interner.debug_assert_args_compatible(kind.into(), args);
626 Self { kind, args, _use_alias_new_instead: () }
627 }
628
629 pub fn free_to_alias_ty(self) -> AliasTy<I> {
630 AliasTy {
631 kind: AliasTyKind::Free { def_id: self.kind },
632 args: self.args,
633 _use_alias_new_instead: (),
634 }
635 }
636}
637
501638#[derive(Clone, Copy, PartialEq, Eq, Debug)]
502639pub enum IntVarValue {
503640 Unknown,
src/tools/clippy/clippy_lints/src/functions/must_use.rs+1-4
......@@ -4,7 +4,6 @@ use rustc_errors::Applicability;
44use rustc_hir::def::Res;
55use rustc_hir::def_id::DefIdSet;
66use rustc_hir::{self as hir, Attribute, QPath, find_attr};
7use rustc_infer::infer::TyCtxtInferExt;
87use rustc_lint::{LateContext, LintContext};
98use rustc_middle::ty::{self, Ty};
109use rustc_span::{Span, sym};
......@@ -16,7 +15,6 @@ use clippy_utils::ty::is_must_use_ty;
1615use clippy_utils::visitors::for_each_expr_without_closures;
1716use clippy_utils::{is_entrypoint_fn, return_ty, trait_ref_of_method};
1817use rustc_span::Symbol;
19use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
2018
2119use core::ops::ControlFlow;
2220
......@@ -166,8 +164,7 @@ fn check_needless_must_use(
166164 } else if reason.is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
167165 // Ignore async functions unless Future::Output type is a must_use type
168166 if sig.header.is_async() {
169 let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
170 if let Some(future_ty) = infcx.err_ctxt().get_impl_future_output_ty(return_ty(cx, item_id))
167 if let Some(future_ty) = cx.tcx.get_impl_future_output_ty(return_ty(cx, item_id))
171168 && !is_must_use_ty(cx, future_ty)
172169 {
173170 return;
src/tools/clippy/clippy_lints/src/functions/result.rs+1-8
......@@ -2,12 +2,10 @@ use clippy_utils::msrvs::{self, Msrv};
22use clippy_utils::res::MaybeDef;
33use rustc_errors::Diag;
44use rustc_hir as hir;
5use rustc_infer::infer::TyCtxtInferExt as _;
65use rustc_lint::{LateContext, LintContext};
76use rustc_middle::ty::{self, Ty};
87use rustc_span::def_id::DefIdSet;
98use rustc_span::{Span, sym};
10use rustc_trait_selection::error_reporting::InferCtxtErrorExt as _;
119
1210use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
1311use clippy_utils::ty::{AdtVariantInfo, approx_ty_size};
......@@ -32,12 +30,7 @@ fn result_err_ty<'tcx>(
3230
3331 // for async functions, peel through `impl Future<Output = T>` to get `T`
3432 if cx.tcx.ty_is_opaque_future(ty)
35 && let Some(future_output_ty) = cx
36 .tcx
37 .infer_ctxt()
38 .build(cx.typing_mode())
39 .err_ctxt()
40 .get_impl_future_output_ty(ty)
33 && let Some(future_output_ty) = cx.tcx.get_impl_future_output_ty(ty)
4134 {
4235 ty = future_output_ty;
4336 }
src/tools/clippy/clippy_lints/src/len_without_is_empty.rs+5-2
......@@ -149,8 +149,11 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Iden
149149}
150150
151151fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> {
152 if let ty::Alias(alias_ty) = ty.kind()
153 && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(alias_ty.kind.def_id())
152 if let ty::Alias(ty::AliasTy {
153 kind: ty::Opaque { def_id },
154 ..
155 }) = *ty.kind()
156 && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(def_id)
154157 && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
155158 && let [GenericBound::Trait(trait_ref)] = &opaque.bounds
156159 && let Some(segment) = trait_ref.trait_ref.path.segments.last()
src/tools/clippy/clippy_lints/src/methods/needless_collect.rs+1-5
......@@ -247,11 +247,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty:
247247 && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty])
248248 && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions(
249249 cx.typing_env(),
250 Unnormalized::new_wip(Ty::new_projection_from_args(
251 cx.tcx,
252 into_iter_item_proj.kind.def_id(),
253 into_iter_item_proj.args,
254 )),
250 Unnormalized::new_wip(Ty::new_alias(cx.tcx, into_iter_item_proj)),
255251 )
256252 {
257253 iter_item_ty == into_iter_item_ty
src/tools/clippy/clippy_lints/src/no_effect.rs+1-8
......@@ -9,11 +9,9 @@ use rustc_hir::{
99 BinOpKind, BlockCheckMode, Expr, ExprKind, HirId, HirIdMap, ItemKind, LocalSource, Node, PatKind, Stmt, StmtKind,
1010 StructTailExpr, UnsafeSource, is_range_literal,
1111};
12use rustc_infer::infer::TyCtxtInferExt as _;
1312use rustc_lint::{LateContext, LateLintPass, LintContext};
1413use rustc_session::impl_lint_pass;
1514use rustc_span::Span;
16use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
1715use std::ops::Deref;
1816
1917declare_clippy_lint! {
......@@ -162,12 +160,7 @@ impl NoEffect {
162160
163161 // Remove `impl Future<Output = T>` to get `T`
164162 if cx.tcx.ty_is_opaque_future(ret_ty)
165 && let Some(true_ret_ty) = cx
166 .tcx
167 .infer_ctxt()
168 .build(cx.typing_mode())
169 .err_ctxt()
170 .get_impl_future_output_ty(ret_ty)
163 && let Some(true_ret_ty) = cx.tcx.get_impl_future_output_ty(ret_ty)
171164 {
172165 ret_ty = true_ret_ty;
173166 }
src/tools/clippy/clippy_utils/src/ty/mod.rs+8-18
......@@ -20,8 +20,9 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind};
2020use rustc_middle::ty::layout::ValidityRequirement;
2121use rustc_middle::ty::{
2222 self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, BoundVarIndexKind, FnSig, GenericArg,
23 GenericArgKind, GenericArgsRef, IntTy, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
24 TypeVisitableExt, TypeVisitor, UintTy, Unnormalized, Upcast, VariantDef, VariantDiscr,
23 GenericArgKind, GenericArgsRef, IntTy, ProjectionAliasTy, Region, RegionKind, TraitRef, Ty, TyCtxt,
24 TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Unnormalized, Upcast, VariantDef,
25 VariantDiscr,
2526};
2627use rustc_span::symbol::Ident;
2728use rustc_span::{DUMMY_SP, Span, Symbol};
......@@ -669,12 +670,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
669670 _ => None,
670671 }
671672 },
672 ty::Alias(
673 proj @ AliasTy {
674 kind: ty::Projection { .. },
675 ..
676 },
677 ) => match cx
673 ty::Alias(alias) if let Some(proj) = alias.try_to_projection() => match cx
678674 .tcx
679675 .try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty))
680676 {
......@@ -728,14 +724,14 @@ fn sig_from_bounds<'tcx>(
728724 inputs.map(|ty| ExprFnSig::Trait(ty, output, predicates_id))
729725}
730726
731fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option<ExprFnSig<'tcx>> {
727fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionAliasTy<'tcx>) -> Option<ExprFnSig<'tcx>> {
732728 let mut inputs = None;
733729 let mut output = None;
734730 let lang_items = cx.tcx.lang_items();
735731
736732 for (pred, _) in cx
737733 .tcx
738 .explicit_item_bounds(ty.kind.def_id())
734 .explicit_item_bounds(ty.kind)
739735 .iter_instantiated_copied(cx.tcx, ty.args)
740736 .map(Unnormalized::skip_norm_wip)
741737 {
......@@ -1097,10 +1093,7 @@ pub fn make_normalized_projection<'tcx>(
10971093 );
10981094 return None;
10991095 }
1100 match tcx.try_normalize_erasing_regions(
1101 typing_env,
1102 Unnormalized::new_wip(Ty::new_projection_from_args(tcx, ty.kind.def_id(), ty.args)),
1103 ) {
1096 match tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(Ty::new_alias(tcx, ty))) {
11041097 Ok(ty) => Some(ty),
11051098 Err(e) => {
11061099 debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}");
......@@ -1254,10 +1247,7 @@ pub fn make_normalized_projection_with_regions<'tcx>(
12541247 }
12551248 let cause = ObligationCause::dummy();
12561249 let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
1257 match infcx
1258 .at(&cause, param_env)
1259 .query_normalize(Ty::new_projection_from_args(tcx, ty.kind.def_id(), ty.args))
1260 {
1250 match infcx.at(&cause, param_env).query_normalize(Ty::new_alias(tcx, ty)) {
12611251 Ok(ty) => Some(ty.value),
12621252 Err(e) => {
12631253 debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}");