| author | bors <bors@rust-lang.org> 2026-06-23 17:44:39 UTC |
| committer | bors <bors@rust-lang.org> 2026-06-23 17:44:39 UTC |
| log | f28ac764c36004fa6a6e098d15b4016a838c13c6 |
| tree | c6df7081c940cba8b4289c531f37e5c9b5b81dbc |
| parent | 4429659e4745016bd3f26a4a421843edc7fbc422 |
| parent | 992c2de84a5c80da85886246b3a2e57a2f8e7146 |
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? @BoxyUwU39 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>( |
| 83 | 83 | |
| 84 | 84 | for trait_projection in collector.types.into_iter().rev() { |
| 85 | 85 | 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(); | |
| 89 | 88 | |
| 90 | 89 | // 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 { | |
| 95 | 95 | report_mismatched_rpitit_signature( |
| 96 | 96 | tcx, |
| 97 | 97 | trait_m_sig_with_self_for_diag, |
| ... | ... | @@ -105,7 +105,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( |
| 105 | 105 | |
| 106 | 106 | // This opaque also needs to be from the impl method -- otherwise, |
| 107 | 107 | // 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| { | |
| 109 | 109 | matches!( |
| 110 | 110 | node.expect_opaque_ty().origin, |
| 111 | 111 | hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. } |
| ... | ... | @@ -124,13 +124,13 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | 126 | trait_bounds.extend( |
| 127 | tcx.item_bounds(trait_projection.kind.def_id()) | |
| 127 | tcx.item_bounds(trait_projection.kind) | |
| 128 | 128 | .iter_instantiated(tcx, trait_projection.args) |
| 129 | 129 | .map(Unnormalized::skip_norm_wip), |
| 130 | 130 | ); |
| 131 | 131 | impl_bounds.extend(elaborate( |
| 132 | 132 | tcx, |
| 133 | tcx.explicit_item_bounds(impl_opaque_def_id) | |
| 133 | tcx.explicit_item_bounds(impl_opaque.kind) | |
| 134 | 134 | .iter_instantiated_copied(tcx, impl_opaque.args) |
| 135 | 135 | .map(Unnormalized::skip_norm_wip), |
| 136 | 136 | )); |
| ... | ... | @@ -231,7 +231,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( |
| 231 | 231 | // is literally unrepresentable in the type system; however, we may be |
| 232 | 232 | // promising stronger outlives guarantees if we capture *fewer* regions. |
| 233 | 233 | 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); | |
| 235 | 235 | let impl_captures: FxIndexSet<_> = impl_opaque |
| 236 | 236 | .args |
| 237 | 237 | .iter() |
| ... | ... | @@ -240,7 +240,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( |
| 240 | 240 | .map(|(arg, _)| arg) |
| 241 | 241 | .collect(); |
| 242 | 242 | |
| 243 | let trait_variances = tcx.variances_of(trait_projection.kind.def_id()); | |
| 243 | let trait_variances = tcx.variances_of(trait_projection.kind); | |
| 244 | 244 | let mut trait_captures = FxIndexSet::default(); |
| 245 | 245 | for (arg, variance) in trait_projection.args.iter().zip_eq(trait_variances) { |
| 246 | 246 | if *variance != ty::Invariant { |
| ... | ... | @@ -252,7 +252,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( |
| 252 | 252 | if !trait_captures.iter().all(|arg| impl_captures.contains(arg)) { |
| 253 | 253 | report_mismatched_rpitit_captures( |
| 254 | 254 | tcx, |
| 255 | impl_opaque.kind.def_id().expect_local(), | |
| 255 | impl_opaque.kind.expect_local(), | |
| 256 | 256 | trait_captures, |
| 257 | 257 | is_internal, |
| 258 | 258 | ); |
| ... | ... | @@ -262,18 +262,19 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( |
| 262 | 262 | |
| 263 | 263 | struct ImplTraitInTraitCollector<'tcx> { |
| 264 | 264 | tcx: TyCtxt<'tcx>, |
| 265 | types: FxIndexSet<ty::AliasTy<'tcx>>, | |
| 265 | types: FxIndexSet<ty::ProjectionAliasTy<'tcx>>, | |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | 268 | impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'tcx> { |
| 269 | 269 | 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) | |
| 272 | 273 | { |
| 273 | 274 | if self.types.insert(proj) { |
| 274 | 275 | for (pred, _) in self |
| 275 | 276 | .tcx |
| 276 | .explicit_item_bounds(def_id) | |
| 277 | .explicit_item_bounds(proj.kind) | |
| 277 | 278 | .iter_instantiated_copied(self.tcx, proj.args) |
| 278 | 279 | .map(Unnormalized::skip_norm_wip) |
| 279 | 280 | { |
compiler/rustc_hir_analysis/src/check/mod.rs+2-12| ... | ... | @@ -89,7 +89,6 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; |
| 89 | 89 | use rustc_middle::ty::print::with_types_for_signature; |
| 90 | 90 | use rustc_middle::ty::{ |
| 91 | 91 | self, GenericArgs, GenericArgsRef, OutlivesPredicate, Region, Ty, TyCtxt, TypingMode, |
| 92 | Unnormalized, | |
| 93 | 92 | }; |
| 94 | 93 | use rustc_middle::{bug, span_bug}; |
| 95 | 94 | use rustc_session::errors::feature_err; |
| ... | ... | @@ -487,21 +486,12 @@ fn fn_sig_suggestion<'tcx>( |
| 487 | 486 | let mut output = sig.output(); |
| 488 | 487 | |
| 489 | 488 | 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(|| { | |
| 500 | 490 | span_bug!( |
| 501 | 491 | ident.span, |
| 502 | 492 | "expected async fn to have `impl Future` output, but it returns {output}" |
| 503 | 493 | ) |
| 504 | }; | |
| 494 | }); | |
| 505 | 495 | "async " |
| 506 | 496 | } else { |
| 507 | 497 | "" |
compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs+5-1| ... | ... | @@ -1356,7 +1356,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 1356 | 1356 | )? { |
| 1357 | 1357 | TypeRelativePath::AssocItem(alias_term) => { |
| 1358 | 1358 | 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 | }; | |
| 1360 | 1364 | let ty = alias_ty.to_ty(tcx); |
| 1361 | 1365 | let ty = self.check_param_uses_if_mcg(ty, span, false); |
| 1362 | 1366 | 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> { |
| 2910 | 2910 | base: &'tcx hir::Expr<'tcx>, |
| 2911 | 2911 | ty: Ty<'tcx>, |
| 2912 | 2912 | ) { |
| 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 { | |
| 2914 | 2914 | err.span_label(field_ident.span, "unknown field"); |
| 2915 | 2915 | return; |
| 2916 | 2916 | }; |
compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs+1-1| ... | ... | @@ -1351,7 +1351,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 1351 | 1351 | .instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars)); |
| 1352 | 1352 | let ty = match self.tcx.asyncness(fn_id) { |
| 1353 | 1353 | 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(|| { | |
| 1355 | 1355 | span_bug!( |
| 1356 | 1356 | fn_decl.output.span(), |
| 1357 | 1357 | "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> { |
| 3878 | 3878 | span: Span, |
| 3879 | 3879 | return_type: Option<Ty<'tcx>>, |
| 3880 | 3880 | ) { |
| 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 }; | |
| 3882 | 3882 | let output_ty = self.resolve_vars_if_possible(output_ty); |
| 3883 | 3883 | let method_exists = |
| 3884 | 3884 | 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> { |
| 380 | 380 | .map(|(k, h)| (k, h.ty)) |
| 381 | 381 | .collect() |
| 382 | 382 | } |
| 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>> { | |
| 384 | 384 | self.opaques_with_sub_unified_hidden_type(ty) |
| 385 | 385 | } |
| 386 | 386 |
compiler/rustc_infer/src/infer/mod.rs+6-3| ... | ... | @@ -1115,7 +1115,10 @@ impl<'tcx> InferCtxt<'tcx> { |
| 1115 | 1115 | /// Searches for an opaque type key whose hidden type is related to `ty_vid`. |
| 1116 | 1116 | /// |
| 1117 | 1117 | /// 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>> { | |
| 1119 | 1122 | // Avoid accidentally allowing more code to compile with the old solver. |
| 1120 | 1123 | if !self.next_trait_solver() { |
| 1121 | 1124 | return vec![]; |
| ... | ... | @@ -1133,9 +1136,9 @@ impl<'tcx> InferCtxt<'tcx> { |
| 1133 | 1136 | if let ty::Infer(ty::TyVar(hidden_vid)) = *hidden_ty.ty.kind() { |
| 1134 | 1137 | let opaque_sub_vid = type_variables.sub_unification_table_root_var(hidden_vid); |
| 1135 | 1138 | if opaque_sub_vid == ty_sub_vid { |
| 1136 | return Some(ty::AliasTy::new_from_args( | |
| 1139 | return Some(ty::OpaqueAliasTy::new_opaque_from_args( | |
| 1137 | 1140 | self.tcx, |
| 1138 | ty::Opaque { def_id: key.def_id.into() }, | |
| 1141 | key.def_id.into(), | |
| 1139 | 1142 | key.args, |
| 1140 | 1143 | )); |
| 1141 | 1144 | } |
compiler/rustc_infer/src/infer/outlives/for_liveness.rs+7-1| ... | ... | @@ -59,8 +59,14 @@ where |
| 59 | 59 | ty::Alias(ty::AliasTy { kind, args, .. }) => { |
| 60 | 60 | let tcx = self.tcx; |
| 61 | 61 | 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 | }; | |
| 62 | 68 | let outlives_bounds: Vec<_> = tcx |
| 63 | .item_bounds(kind.def_id()) | |
| 69 | .item_bounds(def_id) | |
| 64 | 70 | .iter_instantiated(tcx, args) |
| 65 | 71 | .map(Unnormalized::skip_norm_wip) |
| 66 | 72 | .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> { |
| 236 | 236 | // And therefore we can safely use structural equality for alias types. |
| 237 | 237 | (GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {} |
| 238 | 238 | (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 => {} | |
| 241 | 240 | _ => return None, |
| 242 | 241 | } |
| 243 | 242 |
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 |
| 385 | 385 | | ty::CoroutineWitness(def_id, _) |
| 386 | 386 | | ty::Foreign(def_id) => Some(def_id), |
| 387 | 387 | |
| 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 | }, | |
| 389 | 394 | |
| 390 | 395 | ty::Bool |
| 391 | 396 | | ty::Char |
compiler/rustc_middle/src/ty/context.rs+33| ... | ... | @@ -2704,6 +2704,39 @@ impl<'tcx> TyCtxt<'tcx> { |
| 2704 | 2704 | self.opt_rpitit_info(def_id).is_some() |
| 2705 | 2705 | } |
| 2706 | 2706 | |
| 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 | ||
| 2707 | 2740 | /// Named module children from all kinds of items, including imports. |
| 2708 | 2741 | /// In addition to regular items this list also includes struct and variant constructors, and |
| 2709 | 2742 | /// 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::{ |
| 104 | 104 | EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region, RegionKind, RegionVid, |
| 105 | 105 | }; |
| 106 | 106 | pub 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, | |
| 112 | 113 | }; |
| 113 | 114 | pub use self::trait_def::TraitDef; |
| 114 | 115 | pub 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 { |
| 1369 | 1369 | self.tcx().opt_rpitit_info(def_id) |
| 1370 | 1370 | && let ty::Alias(alias_ty) = |
| 1371 | 1371 | 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 | |
| 1373 | 1374 | && let generics = self.tcx().generics_of(fn_def_id) |
| 1374 | 1375 | // 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)) | |
| 1376 | 1380 | { |
| 1377 | 1381 | let num_args = generics.count(); |
| 1378 | 1382 | 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>>; |
| 38 | 38 | pub type TypeAndMut<'tcx> = ir::TypeAndMut<TyCtxt<'tcx>>; |
| 39 | 39 | pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>; |
| 40 | 40 | pub type AliasTyKind<'tcx> = ir::AliasTyKind<TyCtxt<'tcx>>; |
| 41 | pub type Alias<'tcx, K> = ir::Alias<TyCtxt<'tcx>, K>; | |
| 42 | pub type ProjectionAliasTy<'tcx> = ir::ProjectionAliasTy<TyCtxt<'tcx>>; | |
| 43 | pub type InherentAliasTy<'tcx> = ir::InherentAliasTy<TyCtxt<'tcx>>; | |
| 44 | pub type OpaqueAliasTy<'tcx> = ir::OpaqueAliasTy<TyCtxt<'tcx>>; | |
| 45 | pub type FreeAliasTy<'tcx> = ir::FreeAliasTy<TyCtxt<'tcx>>; | |
| 41 | 46 | pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>; |
| 42 | 47 | pub type FnSigKind<'tcx> = ir::FnSigKind<TyCtxt<'tcx>>; |
| 43 | 48 | pub type Binder<'tcx, T> = ir::Binder<TyCtxt<'tcx>, T>; |
| ... | ... | @@ -477,12 +482,22 @@ impl<'tcx> Ty<'tcx> { |
| 477 | 482 | |
| 478 | 483 | #[inline] |
| 479 | 484 | 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 | } | |
| 486 | 501 | Ty::new(tcx, Alias(alias_ty)) |
| 487 | 502 | } |
| 488 | 503 |
compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs+22-17| ... | ... | @@ -741,7 +741,7 @@ where |
| 741 | 741 | candidates: &mut Vec<Candidate<I>>, |
| 742 | 742 | consider_self_bounds: AliasBoundKind, |
| 743 | 743 | ) -> Result<(), RerunNonErased> { |
| 744 | let alias_ty = match self_ty.kind() { | |
| 744 | let (alias_ty, def_id) = match self_ty.kind() { | |
| 745 | 745 | ty::Bool |
| 746 | 746 | | ty::Char |
| 747 | 747 | | ty::Int(_) |
| ... | ... | @@ -789,9 +789,12 @@ where |
| 789 | 789 | return Ok(()); |
| 790 | 790 | } |
| 791 | 791 | |
| 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 | } | |
| 795 | 798 | ty::Alias(AliasTy { kind: ty::Inherent { .. } | ty::Free { .. }, .. }) => { |
| 796 | 799 | self.cx().delay_bug(format!("could not normalize {self_ty:?}, it is not WF")); |
| 797 | 800 | return Ok(()); |
| ... | ... | @@ -802,7 +805,7 @@ where |
| 802 | 805 | AliasBoundKind::SelfBounds => { |
| 803 | 806 | for assumption in self |
| 804 | 807 | .cx() |
| 805 | .item_self_bounds(alias_ty.kind.def_id()) | |
| 808 | .item_self_bounds(def_id) | |
| 806 | 809 | .iter_instantiated(self.cx(), alias_ty.args) |
| 807 | 810 | .map(Unnormalized::skip_norm_wip) |
| 808 | 811 | { |
| ... | ... | @@ -818,7 +821,7 @@ where |
| 818 | 821 | AliasBoundKind::NonSelfBounds => { |
| 819 | 822 | for assumption in self |
| 820 | 823 | .cx() |
| 821 | .item_non_self_bounds(alias_ty.kind.def_id()) | |
| 824 | .item_non_self_bounds(def_id) | |
| 822 | 825 | .iter_instantiated(self.cx(), alias_ty.args) |
| 823 | 826 | .map(Unnormalized::skip_norm_wip) |
| 824 | 827 | { |
| ... | ... | @@ -835,12 +838,12 @@ where |
| 835 | 838 | |
| 836 | 839 | candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty)); |
| 837 | 840 | |
| 838 | if !matches!(alias_ty.kind, ty::Projection { .. }) { | |
| 841 | let Some(projection_ty) = alias_ty.try_to_projection() else { | |
| 839 | 842 | return Ok(()); |
| 840 | } | |
| 843 | }; | |
| 841 | 844 | |
| 842 | 845 | // 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()) { | |
| 844 | 847 | Ok(next_self_ty) => self.assemble_alias_bound_candidates_recur( |
| 845 | 848 | next_self_ty, |
| 846 | 849 | goal, |
| ... | ... | @@ -1072,12 +1075,12 @@ where |
| 1072 | 1075 | return Ok(()); |
| 1073 | 1076 | } |
| 1074 | 1077 | |
| 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:?}"); | |
| 1077 | 1080 | |
| 1078 | 1081 | struct ReplaceOpaque<I: Interner> { |
| 1079 | 1082 | cx: I, |
| 1080 | alias_ty: ty::AliasTy<I>, | |
| 1083 | opaque_ty: ty::OpaqueAliasTy<I>, | |
| 1081 | 1084 | self_ty: I::Ty, |
| 1082 | 1085 | } |
| 1083 | 1086 | impl<I: Interner> TypeFolder<I> for ReplaceOpaque<I> { |
| ... | ... | @@ -1085,8 +1088,10 @@ where |
| 1085 | 1088 | self.cx |
| 1086 | 1089 | } |
| 1087 | 1090 | 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 { | |
| 1090 | 1095 | return self.self_ty; |
| 1091 | 1096 | } |
| 1092 | 1097 | } |
| ... | ... | @@ -1103,12 +1108,12 @@ where |
| 1103 | 1108 | // in a `?x: Trait<u32>` alias-bound candidate. |
| 1104 | 1109 | for item_bound in self |
| 1105 | 1110 | .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) | |
| 1108 | 1113 | .map(Unnormalized::skip_norm_wip) |
| 1109 | 1114 | { |
| 1110 | 1115 | 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 }); | |
| 1112 | 1117 | candidates.extend(G::probe_and_match_goal_against_assumption( |
| 1113 | 1118 | self, |
| 1114 | 1119 | CandidateSource::AliasBound(AliasBoundKind::SelfBounds), |
compiler/rustc_next_trait_solver/src/solve/effect_goals.rs+16-9| ... | ... | @@ -86,17 +86,24 @@ where |
| 86 | 86 | let cx = ecx.cx(); |
| 87 | 87 | let mut candidates = vec![]; |
| 88 | 88 | |
| 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) { | |
| 90 | 97 | return vec![]; |
| 91 | 98 | } |
| 92 | 99 | |
| 93 | 100 | for clause in elaborate::elaborate( |
| 94 | 101 | 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| { | |
| 98 | 104 | trait_ref.to_host_effect_clause(cx, goal.predicate.constness).skip_norm_wip() |
| 99 | }), | |
| 105 | }, | |
| 106 | ), | |
| 100 | 107 | ) { |
| 101 | 108 | candidates.extend(Self::probe_and_match_goal_against_assumption( |
| 102 | 109 | ecx, |
| ... | ... | @@ -107,16 +114,16 @@ where |
| 107 | 114 | // Const conditions must hold for the implied const bound to hold. |
| 108 | 115 | ecx.add_goals( |
| 109 | 116 | 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| { | |
| 113 | 119 | goal.with( |
| 114 | 120 | cx, |
| 115 | 121 | trait_ref |
| 116 | 122 | .to_host_effect_clause(cx, goal.predicate.constness) |
| 117 | 123 | .skip_norm_wip(), |
| 118 | 124 | ) |
| 119 | }), | |
| 125 | }, | |
| 126 | ), | |
| 120 | 127 | ); |
| 121 | 128 | ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) |
| 122 | 129 | }, |
compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs+1-1| ... | ... | @@ -1588,7 +1588,7 @@ where |
| 1588 | 1588 | pub(crate) fn opaques_with_sub_unified_hidden_type( |
| 1589 | 1589 | &self, |
| 1590 | 1590 | self_ty: I::Ty, |
| 1591 | ) -> Vec<ty::AliasTy<I>> { | |
| 1591 | ) -> Vec<ty::OpaqueAliasTy<I>> { | |
| 1592 | 1592 | if let ty::Infer(ty::TyVar(vid)) = self_ty.kind() { |
| 1593 | 1593 | self.delegate.opaques_with_sub_unified_hidden_type(vid) |
| 1594 | 1594 | } else { |
compiler/rustc_public/src/unstable/convert/stable/ty.rs+8-4| ... | ... | @@ -32,10 +32,14 @@ impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> { |
| 32 | 32 | cx: &CompilerCtxt<'cx, BridgeTys>, |
| 33 | 33 | ) -> Self::T { |
| 34 | 34 | 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) } | |
| 39 | 43 | } |
| 40 | 44 | } |
| 41 | 45 |
compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs-35| ... | ... | @@ -56,7 +56,6 @@ use rustc_errors::{Applicability, Diag, DiagStyledString, IntoDiagArg, StringPar |
| 56 | 56 | use rustc_hir::attrs::diagnostic::{CustomDiagnostic, Directive, FormatArgs}; |
| 57 | 57 | use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; |
| 58 | 58 | use rustc_hir::intravisit::Visitor; |
| 59 | use rustc_hir::lang_items::LangItem; | |
| 60 | 59 | use rustc_hir::{self as hir, find_attr}; |
| 61 | 60 | use rustc_infer::infer::DefineOpaqueTypes; |
| 62 | 61 | use rustc_macros::extension; |
| ... | ... | @@ -207,40 +206,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { |
| 207 | 206 | ) |
| 208 | 207 | } |
| 209 | 208 | |
| 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 | ||
| 244 | 209 | /// Adds a note if the types come from similarly named crates |
| 245 | 210 | fn check_and_note_conflicting_crates(&self, err: &mut Diag<'_>, terr: TypeError<'tcx>) -> bool { |
| 246 | 211 | 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> { |
| 126 | 126 | region_def_id: DefId, |
| 127 | 127 | hir_sig: &hir::FnSig<'_>, |
| 128 | 128 | ) -> 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(); | |
| 130 | 131 | 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(); | |
| 132 | 133 | let span = hir_sig.decl.output.span(); |
| 133 | 134 | 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() | |
| 135 | 136 | } else { |
| 136 | 137 | None |
| 137 | 138 | }; |
compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs+18-10| ... | ... | @@ -627,19 +627,19 @@ impl<T> Trait<T> for X { |
| 627 | 627 | diag: &mut Diag<'_>, |
| 628 | 628 | msg: impl Fn() -> String, |
| 629 | 629 | body_owner_def_id: Option<DefId>, |
| 630 | proj_ty: ty::AliasTy<'tcx>, | |
| 630 | alias_ty: ty::AliasTy<'tcx>, | |
| 631 | 631 | ty: Ty<'tcx>, |
| 632 | 632 | ) -> bool { |
| 633 | 633 | let tcx = self.tcx; |
| 634 | 634 | // 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 { | |
| 636 | 636 | return false; |
| 637 | } | |
| 637 | }; | |
| 638 | 638 | let Some(body_owner_def_id) = body_owner_def_id else { |
| 639 | 639 | return false; |
| 640 | 640 | }; |
| 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); | |
| 643 | 643 | let Some(item) = tcx.hir_get_if_local(body_owner_def_id) else { |
| 644 | 644 | return false; |
| 645 | 645 | }; |
| ... | ... | @@ -648,7 +648,7 @@ impl<T> Trait<T> for X { |
| 648 | 648 | }; |
| 649 | 649 | // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`. |
| 650 | 650 | // 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 { | |
| 652 | 652 | return false; |
| 653 | 653 | }; |
| 654 | 654 | let generics = tcx.generics_of(body_owner_def_id); |
| ... | ... | @@ -684,7 +684,7 @@ impl<T> Trait<T> for X { |
| 684 | 684 | _ => return false, |
| 685 | 685 | }; |
| 686 | 686 | 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) | |
| 688 | 688 | } |
| 689 | 689 | |
| 690 | 690 | /// An associated type was expected and a different type was found. |
| ... | ... | @@ -719,6 +719,10 @@ impl<T> Trait<T> for X { |
| 719 | 719 | return; |
| 720 | 720 | } |
| 721 | 721 | |
| 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 | ||
| 722 | 726 | let msg = || { |
| 723 | 727 | format!( |
| 724 | 728 | "consider constraining the associated type `{}` to `{}`", |
| ... | ... | @@ -746,9 +750,9 @@ impl<T> Trait<T> for X { |
| 746 | 750 | let point_at_assoc_fn = if callable_scope |
| 747 | 751 | && self.point_at_methods_that_satisfy_associated_type( |
| 748 | 752 | diag, |
| 749 | tcx.parent(proj_ty.kind.def_id()), | |
| 753 | tcx.parent(def_id), | |
| 750 | 754 | current_method_ident, |
| 751 | proj_ty.kind.def_id(), | |
| 755 | def_id, | |
| 752 | 756 | values.expected, |
| 753 | 757 | ) { |
| 754 | 758 | // If we find a suitable associated function that returns the expected type, we |
| ... | ... | @@ -821,7 +825,11 @@ fn foo(&self) -> Self::T { String::new() } |
| 821 | 825 | ) -> bool { |
| 822 | 826 | let tcx = self.tcx; |
| 823 | 827 | |
| 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); | |
| 825 | 833 | if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = |
| 826 | 834 | *proj_ty.self_ty().kind() |
| 827 | 835 | { |
compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs+2-2| ... | ... | @@ -190,8 +190,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { |
| 190 | 190 | } |
| 191 | 191 | |
| 192 | 192 | 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), | |
| 195 | 195 | ) { |
| 196 | 196 | (Some(exp), Some(found)) if self.same_type_modulo_infer(exp, found) => match cause |
| 197 | 197 | .code() |
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs+10-9| ... | ... | @@ -128,7 +128,7 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>( |
| 128 | 128 | msg: &str, |
| 129 | 129 | err: &mut Diag<'_, G>, |
| 130 | 130 | fn_sig: Option<&hir::FnSig<'_>>, |
| 131 | projection: Option<ty::AliasTy<'_>>, | |
| 131 | projection: Option<ty::ProjectionAliasTy<'_>>, | |
| 132 | 132 | trait_pred: ty::PolyTraitPredicate<'tcx>, |
| 133 | 133 | // When we are dealing with a trait, `super_traits` will be `Some`: |
| 134 | 134 | // Given `trait T: A + B + C {}` |
| ... | ... | @@ -140,11 +140,8 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>( |
| 140 | 140 | if hir_generics.where_clause_span.from_expansion() |
| 141 | 141 | || hir_generics.where_clause_span.desugaring_kind().is_some() |
| 142 | 142 | || 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()) | |
| 148 | 145 | }) |
| 149 | 146 | { |
| 150 | 147 | return; |
| ... | ... | @@ -152,7 +149,7 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>( |
| 152 | 149 | let generics = tcx.generics_of(item_id); |
| 153 | 150 | // Given `fn foo(t: impl Trait)` where `Trait` requires assoc type `A`... |
| 154 | 151 | 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() { | |
| 156 | 153 | // Shenanigans to get the `Trait` from the `impl Trait`. |
| 157 | 154 | ty::Param(param) => { |
| 158 | 155 | let param_def = generics.type_param(param, tcx); |
| ... | ... | @@ -479,8 +476,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { |
| 479 | 476 | let self_ty = trait_pred.skip_binder().self_ty(); |
| 480 | 477 | let (param_ty, projection) = match *self_ty.kind() { |
| 481 | 478 | 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 | } | |
| 484 | 485 | } |
| 485 | 486 | _ => (false, None), |
| 486 | 487 | }; |
compiler/rustc_trait_selection/src/traits/effects.rs+3-4| ... | ... | @@ -218,7 +218,7 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>( |
| 218 | 218 | if candidate.is_some() { |
| 219 | 219 | return Err(EvaluationFailure::Ambiguous); |
| 220 | 220 | } else { |
| 221 | candidate = Some((data, alias_ty)); | |
| 221 | candidate = Some((data, alias_ty, def_id)); | |
| 222 | 222 | } |
| 223 | 223 | } |
| 224 | 224 | } |
| ... | ... | @@ -231,12 +231,11 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>( |
| 231 | 231 | consider_ty = alias_ty.self_ty(); |
| 232 | 232 | } |
| 233 | 233 | |
| 234 | if let Some((data, alias_ty)) = candidate { | |
| 234 | if let Some((data, alias_ty, def_id)) = candidate { | |
| 235 | 235 | Ok(match_candidate(selcx, obligation, data, true, |selcx, nested| { |
| 236 | 236 | // An alias bound only holds if we also check the const conditions |
| 237 | 237 | // 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); | |
| 240 | 239 | let const_conditions: Vec<_> = const_conditions |
| 241 | 240 | .into_iter() |
| 242 | 241 | .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> { |
| 223 | 223 | } |
| 224 | 224 | |
| 225 | 225 | 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() | |
| 232 | 228 | && let Some( |
| 233 | 229 | ty::ImplTraitInTraitData::Trait { fn_def_id, .. } |
| 234 | 230 | | 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) | |
| 236 | 232 | && fn_def_id == self.fn_def_id |
| 237 | && self.seen.insert(unshifted_alias_ty_def_id) | |
| 233 | && self.seen.insert(unshifted_alias_ty.kind) | |
| 238 | 234 | { |
| 239 | 235 | // We have entered some binders as we've walked into the |
| 240 | 236 | // bounds of the RPITIT. Shift these binders back out when |
| ... | ... | @@ -259,14 +255,14 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { |
| 259 | 255 | // strategy, then just reinterpret the associated type like an opaque :^) |
| 260 | 256 | let default_ty = self |
| 261 | 257 | .tcx |
| 262 | .type_of(shifted_alias_ty.kind.def_id()) | |
| 258 | .type_of(shifted_alias_ty.kind) | |
| 263 | 259 | .instantiate(self.tcx, shifted_alias_ty.args) |
| 264 | 260 | .skip_norm_wip(); |
| 265 | 261 | |
| 266 | 262 | self.predicates.push( |
| 267 | 263 | ty::Binder::bind_with_vars( |
| 268 | 264 | ty::ProjectionPredicate { |
| 269 | projection_term: shifted_alias_ty.into(), | |
| 265 | projection_term: shifted_alias_ty.projection_to_alias_ty().into(), | |
| 270 | 266 | term: default_ty.into(), |
| 271 | 267 | }, |
| 272 | 268 | self.bound_vars, |
| ... | ... | @@ -280,7 +276,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { |
| 280 | 276 | // easier to just do this. |
| 281 | 277 | for bound in self |
| 282 | 278 | .tcx |
| 283 | .item_bounds(unshifted_alias_ty_def_id) | |
| 279 | .item_bounds(unshifted_alias_ty.kind) | |
| 284 | 280 | .iter_instantiated(self.tcx, unshifted_alias_ty.args) |
| 285 | 281 | .map(Unnormalized::skip_norm_wip) |
| 286 | 282 | { |
compiler/rustc_type_ir/src/infer_ctxt.rs+4-1| ... | ... | @@ -502,7 +502,10 @@ pub trait InferCtxtLike: Sized { |
| 502 | 502 | &self, |
| 503 | 503 | prev_entries: Self::OpaqueTypeStorageEntries, |
| 504 | 504 | ) -> 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>>; | |
| 506 | 509 | |
| 507 | 510 | fn register_hidden_type_in_storage( |
| 508 | 511 | &self, |
compiler/rustc_type_ir/src/lib.rs+1-1| ... | ... | @@ -81,7 +81,7 @@ pub use predicate_kind::*; |
| 81 | 81 | pub use region_kind::*; |
| 82 | 82 | pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy}; |
| 83 | 83 | use rustc_type_ir_macros::GenericTypeVisitable; |
| 84 | pub use ty::{Alias, AliasTerm, AliasTy, UnevaluatedConst}; | |
| 84 | pub use ty::{Alias, *}; | |
| 85 | 85 | pub use ty_info::*; |
| 86 | 86 | pub use ty_kind::*; |
| 87 | 87 | pub use unnormalized::Unnormalized; |
compiler/rustc_type_ir/src/outlives.rs+8-1| ... | ... | @@ -264,7 +264,14 @@ pub fn declared_bounds_from_definition<I: Interner>( |
| 264 | 264 | cx: I, |
| 265 | 265 | alias_ty: AliasTy<I>, |
| 266 | 266 | ) -> 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); | |
| 268 | 275 | bounds |
| 269 | 276 | .iter_instantiated(cx, alias_ty.args) |
| 270 | 277 | .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> { |
| 213 | 213 | a: ty::AliasTy<I>, |
| 214 | 214 | b: ty::AliasTy<I>, |
| 215 | 215 | ) -> RelateResult<I, ty::AliasTy<I>> { |
| 216 | if a.kind.def_id() != b.kind.def_id() { | |
| 216 | if a.kind != b.kind { | |
| 217 | 217 | Err(TypeError::ProjectionMismatched(ExpectedFound::new(a.kind.into(), b.kind.into()))) |
| 218 | 218 | } else { |
| 219 | 219 | 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> { |
| 53 | 53 | |
| 54 | 54 | pub type AliasTerm<I> = Alias<I, AliasTermKind<I>>; |
| 55 | 55 | pub type AliasTy<I> = Alias<I, AliasTyKind<I>>; |
| 56 | pub type ProjectionAliasTy<I> = Alias<I, <I as Interner>::TraitAssocTyId>; | |
| 57 | pub type InherentAliasTy<I> = Alias<I, <I as Interner>::InherentAssocTyId>; | |
| 58 | pub type OpaqueAliasTy<I> = Alias<I, <I as Interner>::OpaqueTyId>; | |
| 59 | pub type FreeAliasTy<I> = Alias<I, <I as Interner>::FreeTyAliasId>; | |
| 56 | 60 | pub type UnevaluatedConst<I> = Alias<I, UnevaluatedConstKind<I>>; |
compiler/rustc_type_ir/src/ty/mod.rs+1-1| ... | ... | @@ -1,3 +1,3 @@ |
| 1 | 1 | mod alias; |
| 2 | 2 | |
| 3 | pub use alias::{Alias, AliasTerm, AliasTy, UnevaluatedConst}; | |
| 3 | pub use alias::*; |
compiler/rustc_type_ir/src/ty_kind.rs+144-7| ... | ... | @@ -20,7 +20,10 @@ use crate::inherent::*; |
| 20 | 20 | use crate::ty::AliasTy; |
| 21 | 21 | #[cfg(feature = "nightly")] |
| 22 | 22 | use crate::visit::TypeVisitable; |
| 23 | use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy}; | |
| 23 | use crate::{ | |
| 24 | self as ty, BoundVarIndexKind, FloatTy, FreeAliasTy, InherentAliasTy, IntTy, Interner, | |
| 25 | OpaqueAliasTy, ProjectionAliasTy, UintTy, | |
| 26 | }; | |
| 24 | 27 | |
| 25 | 28 | mod closure; |
| 26 | 29 | |
| ... | ... | @@ -75,12 +78,31 @@ impl<I: Interner> AliasTyKind<I> { |
| 75 | 78 | } |
| 76 | 79 | } |
| 77 | 80 | |
| 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> { | |
| 79 | 103 | 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, | |
| 84 | 106 | } |
| 85 | 107 | } |
| 86 | 108 | } |
| ... | ... | @@ -430,7 +452,15 @@ impl<I: Interner> fmt::Debug for TyKind<I> { |
| 430 | 452 | |
| 431 | 453 | impl<I: Interner> AliasTy<I> { |
| 432 | 454 | 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 | } | |
| 434 | 464 | AliasTy { kind, args, _use_alias_new_instead: () } |
| 435 | 465 | } |
| 436 | 466 | |
| ... | ... | @@ -451,9 +481,67 @@ impl<I: Interner> AliasTy<I> { |
| 451 | 481 | pub fn to_ty(self, interner: I) -> I::Ty { |
| 452 | 482 | Ty::new_alias(interner, self) |
| 453 | 483 | } |
| 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 | ||
| 518 | impl<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 | } | |
| 454 | 540 | } |
| 455 | 541 | |
| 456 | 542 | /// 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) | |
| 457 | 545 | impl<I: Interner> AliasTy<I> { |
| 458 | 546 | #[track_caller] |
| 459 | 547 | pub fn self_ty(self) -> I::Ty { |
| ... | ... | @@ -498,6 +586,55 @@ impl<I: Interner> AliasTy<I> { |
| 498 | 586 | } |
| 499 | 587 | } |
| 500 | 588 | |
| 589 | impl<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 | ||
| 608 | impl<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 | ||
| 623 | impl<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 | ||
| 501 | 638 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] |
| 502 | 639 | pub enum IntVarValue { |
| 503 | 640 | Unknown, |
src/tools/clippy/clippy_lints/src/functions/must_use.rs+1-4| ... | ... | @@ -4,7 +4,6 @@ use rustc_errors::Applicability; |
| 4 | 4 | use rustc_hir::def::Res; |
| 5 | 5 | use rustc_hir::def_id::DefIdSet; |
| 6 | 6 | use rustc_hir::{self as hir, Attribute, QPath, find_attr}; |
| 7 | use rustc_infer::infer::TyCtxtInferExt; | |
| 8 | 7 | use rustc_lint::{LateContext, LintContext}; |
| 9 | 8 | use rustc_middle::ty::{self, Ty}; |
| 10 | 9 | use rustc_span::{Span, sym}; |
| ... | ... | @@ -16,7 +15,6 @@ use clippy_utils::ty::is_must_use_ty; |
| 16 | 15 | use clippy_utils::visitors::for_each_expr_without_closures; |
| 17 | 16 | use clippy_utils::{is_entrypoint_fn, return_ty, trait_ref_of_method}; |
| 18 | 17 | use rustc_span::Symbol; |
| 19 | use rustc_trait_selection::error_reporting::InferCtxtErrorExt; | |
| 20 | 18 | |
| 21 | 19 | use core::ops::ControlFlow; |
| 22 | 20 | |
| ... | ... | @@ -166,8 +164,7 @@ fn check_needless_must_use( |
| 166 | 164 | } else if reason.is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) { |
| 167 | 165 | // Ignore async functions unless Future::Output type is a must_use type |
| 168 | 166 | 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)) | |
| 171 | 168 | && !is_must_use_ty(cx, future_ty) |
| 172 | 169 | { |
| 173 | 170 | return; |
src/tools/clippy/clippy_lints/src/functions/result.rs+1-8| ... | ... | @@ -2,12 +2,10 @@ use clippy_utils::msrvs::{self, Msrv}; |
| 2 | 2 | use clippy_utils::res::MaybeDef; |
| 3 | 3 | use rustc_errors::Diag; |
| 4 | 4 | use rustc_hir as hir; |
| 5 | use rustc_infer::infer::TyCtxtInferExt as _; | |
| 6 | 5 | use rustc_lint::{LateContext, LintContext}; |
| 7 | 6 | use rustc_middle::ty::{self, Ty}; |
| 8 | 7 | use rustc_span::def_id::DefIdSet; |
| 9 | 8 | use rustc_span::{Span, sym}; |
| 10 | use rustc_trait_selection::error_reporting::InferCtxtErrorExt as _; | |
| 11 | 9 | |
| 12 | 10 | use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; |
| 13 | 11 | use clippy_utils::ty::{AdtVariantInfo, approx_ty_size}; |
| ... | ... | @@ -32,12 +30,7 @@ fn result_err_ty<'tcx>( |
| 32 | 30 | |
| 33 | 31 | // for async functions, peel through `impl Future<Output = T>` to get `T` |
| 34 | 32 | 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) | |
| 41 | 34 | { |
| 42 | 35 | ty = future_output_ty; |
| 43 | 36 | } |
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 |
| 149 | 149 | } |
| 150 | 150 | |
| 151 | 151 | fn 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) | |
| 154 | 157 | && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin |
| 155 | 158 | && let [GenericBound::Trait(trait_ref)] = &opaque.bounds |
| 156 | 159 | && 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: |
| 247 | 247 | && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty]) |
| 248 | 248 | && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions( |
| 249 | 249 | 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)), | |
| 255 | 251 | ) |
| 256 | 252 | { |
| 257 | 253 | 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::{ |
| 9 | 9 | BinOpKind, BlockCheckMode, Expr, ExprKind, HirId, HirIdMap, ItemKind, LocalSource, Node, PatKind, Stmt, StmtKind, |
| 10 | 10 | StructTailExpr, UnsafeSource, is_range_literal, |
| 11 | 11 | }; |
| 12 | use rustc_infer::infer::TyCtxtInferExt as _; | |
| 13 | 12 | use rustc_lint::{LateContext, LateLintPass, LintContext}; |
| 14 | 13 | use rustc_session::impl_lint_pass; |
| 15 | 14 | use rustc_span::Span; |
| 16 | use rustc_trait_selection::error_reporting::InferCtxtErrorExt; | |
| 17 | 15 | use std::ops::Deref; |
| 18 | 16 | |
| 19 | 17 | declare_clippy_lint! { |
| ... | ... | @@ -162,12 +160,7 @@ impl NoEffect { |
| 162 | 160 | |
| 163 | 161 | // Remove `impl Future<Output = T>` to get `T` |
| 164 | 162 | 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) | |
| 171 | 164 | { |
| 172 | 165 | ret_ty = true_ret_ty; |
| 173 | 166 | } |
src/tools/clippy/clippy_utils/src/ty/mod.rs+8-18| ... | ... | @@ -20,8 +20,9 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind}; |
| 20 | 20 | use rustc_middle::ty::layout::ValidityRequirement; |
| 21 | 21 | use rustc_middle::ty::{ |
| 22 | 22 | 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, | |
| 25 | 26 | }; |
| 26 | 27 | use rustc_span::symbol::Ident; |
| 27 | 28 | use rustc_span::{DUMMY_SP, Span, Symbol}; |
| ... | ... | @@ -669,12 +670,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t |
| 669 | 670 | _ => None, |
| 670 | 671 | } |
| 671 | 672 | }, |
| 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 | |
| 678 | 674 | .tcx |
| 679 | 675 | .try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty)) |
| 680 | 676 | { |
| ... | ... | @@ -728,14 +724,14 @@ fn sig_from_bounds<'tcx>( |
| 728 | 724 | inputs.map(|ty| ExprFnSig::Trait(ty, output, predicates_id)) |
| 729 | 725 | } |
| 730 | 726 | |
| 731 | fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option<ExprFnSig<'tcx>> { | |
| 727 | fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionAliasTy<'tcx>) -> Option<ExprFnSig<'tcx>> { | |
| 732 | 728 | let mut inputs = None; |
| 733 | 729 | let mut output = None; |
| 734 | 730 | let lang_items = cx.tcx.lang_items(); |
| 735 | 731 | |
| 736 | 732 | for (pred, _) in cx |
| 737 | 733 | .tcx |
| 738 | .explicit_item_bounds(ty.kind.def_id()) | |
| 734 | .explicit_item_bounds(ty.kind) | |
| 739 | 735 | .iter_instantiated_copied(cx.tcx, ty.args) |
| 740 | 736 | .map(Unnormalized::skip_norm_wip) |
| 741 | 737 | { |
| ... | ... | @@ -1097,10 +1093,7 @@ pub fn make_normalized_projection<'tcx>( |
| 1097 | 1093 | ); |
| 1098 | 1094 | return None; |
| 1099 | 1095 | } |
| 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))) { | |
| 1104 | 1097 | Ok(ty) => Some(ty), |
| 1105 | 1098 | Err(e) => { |
| 1106 | 1099 | debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}"); |
| ... | ... | @@ -1254,10 +1247,7 @@ pub fn make_normalized_projection_with_regions<'tcx>( |
| 1254 | 1247 | } |
| 1255 | 1248 | let cause = ObligationCause::dummy(); |
| 1256 | 1249 | 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)) { | |
| 1261 | 1251 | Ok(ty) => Some(ty.value), |
| 1262 | 1252 | Err(e) => { |
| 1263 | 1253 | debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}"); |