diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
28 files changed, 414 insertions, 538 deletions
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs deleted file mode 100644 index 9b02651a8bd..00000000000 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ /dev/null @@ -1,100 +0,0 @@ -//! Bounds are restrictions applied to some types after they've been lowered from the HIR to the -//! [`rustc_middle::ty`] form. - -use rustc_hir::LangItem; -use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; -use rustc_span::Span; - -/// Collects together a list of type bounds. These lists of bounds occur in many places -/// in Rust's syntax: -/// -/// ```text -/// trait Foo: Bar + Baz { } -/// ^^^^^^^^^ supertrait list bounding the `Self` type parameter -/// -/// fn foo<T: Bar + Baz>() { } -/// ^^^^^^^^^ bounding the type parameter `T` -/// -/// impl dyn Bar + Baz -/// ^^^^^^^^^ bounding the type-erased dynamic type -/// ``` -/// -/// Our representation is a bit mixed here -- in some cases, we -/// include the self type (e.g., `trait_bounds`) but in others we do not -#[derive(Default, PartialEq, Eq, Clone, Debug)] -pub(crate) struct Bounds<'tcx> { - clauses: Vec<(ty::Clause<'tcx>, Span)>, -} - -impl<'tcx> Bounds<'tcx> { - pub(crate) fn push_region_bound( - &mut self, - tcx: TyCtxt<'tcx>, - region: ty::PolyTypeOutlivesPredicate<'tcx>, - span: Span, - ) { - self.clauses - .push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).upcast(tcx), span)); - } - - pub(crate) fn push_trait_bound( - &mut self, - tcx: TyCtxt<'tcx>, - bound_trait_ref: ty::PolyTraitRef<'tcx>, - span: Span, - polarity: ty::PredicatePolarity, - ) { - let clause = ( - bound_trait_ref - .map_bound(|trait_ref| { - ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity }) - }) - .upcast(tcx), - span, - ); - // FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands. - if tcx.is_lang_item(bound_trait_ref.def_id(), LangItem::Sized) { - self.clauses.insert(0, clause); - } else { - self.clauses.push(clause); - } - } - - pub(crate) fn push_projection_bound( - &mut self, - tcx: TyCtxt<'tcx>, - projection: ty::PolyProjectionPredicate<'tcx>, - span: Span, - ) { - self.clauses.push(( - projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).upcast(tcx), - span, - )); - } - - pub(crate) fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { - let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span)); - let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]); - // Preferable to put this obligation first, since we report better errors for sized ambiguity. - self.clauses.insert(0, (trait_ref.upcast(tcx), span)); - } - - /// Push a `const` or `~const` bound as a `HostEffect` predicate. - pub(crate) fn push_const_bound( - &mut self, - tcx: TyCtxt<'tcx>, - bound_trait_ref: ty::PolyTraitRef<'tcx>, - constness: ty::BoundConstness, - span: Span, - ) { - if tcx.is_const_trait(bound_trait_ref.def_id()) { - self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, constness), span)); - } else { - tcx.dcx().span_delayed_bug(span, "tried to lower {host:?} bound for non-const trait"); - } - } - - pub(crate) fn clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ { - self.clauses.iter().cloned() - } -} diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index bc0fd4b705d..3236e0a3644 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -15,7 +15,6 @@ use rustc_lint_defs::builtin::{ use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::stability::EvalResult; -use rustc_middle::span_bug; use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::fold::{BottomUpFolder, fold_regions}; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; @@ -35,7 +34,6 @@ use {rustc_attr_parsing as attr, rustc_hir as hir}; use super::compare_impl_item::check_type_bounds; use super::*; -use crate::check::intrinsicck::InlineAsmCtxt; pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) { if !tcx.sess.target.is_abi_supported(abi) { @@ -482,9 +480,9 @@ fn best_definition_site_of_opaque<'tcx>( None } hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { - let scope = tcx.hir().get_defining_scope(tcx.local_def_id_to_hir_id(opaque_def_id)); + let scope = tcx.hir_get_defining_scope(tcx.local_def_id_to_hir_id(opaque_def_id)); let found = if scope == hir::CRATE_HIR_ID { - tcx.hir().walk_toplevel_module(&mut locator) + tcx.hir_walk_toplevel_module(&mut locator) } else { match tcx.hir_node(scope) { Node::Item(it) => locator.visit_item(it), @@ -895,13 +893,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } } - DefKind::GlobalAsm => { - let it = tcx.hir().expect_item(def_id); - let hir::ItemKind::GlobalAsm(asm) = it.kind else { - span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it) - }; - InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, def_id); - } _ => {} } } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 84d5ec4a1e5..c193aad2afd 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -501,7 +501,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id); - let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span(); + let return_span = tcx.hir_fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span(); let cause = ObligationCause::new( return_span, impl_m_def_id, @@ -1033,8 +1033,7 @@ fn report_trait_method_mismatch<'tcx>( // argument pattern and type. let (sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let span = tcx - .hir() - .body_param_names(body) + .hir_body_param_names(body) .zip(sig.decl.inputs.iter()) .map(|(param, ty)| param.span.to(ty.span)) .next() @@ -2105,18 +2104,21 @@ pub(super) fn check_type_bounds<'tcx>( ObligationCause::new(impl_ty_span, impl_ty_def_id, code) }; - let mut obligations: Vec<_> = tcx - .explicit_item_bounds(trait_ty.def_id) - .iter_instantiated_copied(tcx, rebased_args) - .map(|(concrete_ty_bound, span)| { - debug!(?concrete_ty_bound); - traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) - }) - .collect(); + let mut obligations: Vec<_> = util::elaborate( + tcx, + tcx.explicit_item_bounds(trait_ty.def_id).iter_instantiated_copied(tcx, rebased_args).map( + |(concrete_ty_bound, span)| { + debug!(?concrete_ty_bound); + traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) + }, + ), + ) + .collect(); // Only in a const implementation do we need to check that the `~const` item bounds hold. if tcx.is_conditionally_const(impl_ty_def_id) { - obligations.extend( + obligations.extend(util::elaborate( + tcx, tcx.explicit_implied_const_bounds(trait_ty.def_id) .iter_instantiated_copied(tcx, rebased_args) .map(|(c, span)| { @@ -2127,7 +2129,7 @@ pub(super) fn check_type_bounds<'tcx>( c.to_host_effect_clause(tcx, ty::BoundConstness::Maybe), ) }), - ); + )); } debug!(item_bounds=?obligations); @@ -2135,26 +2137,19 @@ pub(super) fn check_type_bounds<'tcx>( // to its definition type. This should be the param-env we use to *prove* the // predicate too, but we don't do that because of performance issues. // See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>. - let trait_projection_ty = Ty::new_projection_from_args(tcx, trait_ty.def_id, rebased_args); - let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity(); let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref); - for mut obligation in util::elaborate(tcx, obligations) { - let normalized_predicate = if infcx.next_trait_solver() { - obligation.predicate.fold_with(&mut ReplaceTy { - tcx, - from: trait_projection_ty, - to: impl_identity_ty, - }) - } else { - ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate) - }; - debug!(?normalized_predicate); - obligation.predicate = normalized_predicate; - - ocx.register_obligation(obligation); + for obligation in &mut obligations { + match ocx.deeply_normalize(&normalize_cause, normalize_param_env, obligation.predicate) { + Ok(pred) => obligation.predicate = pred, + Err(e) => { + return Err(infcx.err_ctxt().report_fulfillment_errors(e)); + } + } } + // Check that all obligations are satisfied by the implementation's // version. + ocx.register_obligations(obligations); let errors = ocx.select_all_or_error(); if !errors.is_empty() { let reported = infcx.err_ctxt().report_fulfillment_errors(errors); @@ -2166,22 +2161,6 @@ pub(super) fn check_type_bounds<'tcx>( ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, assumed_wf_types) } -struct ReplaceTy<'tcx> { - tcx: TyCtxt<'tcx>, - from: Ty<'tcx>, - to: Ty<'tcx>, -} - -impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceTy<'tcx> { - fn cx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if self.from == ty { self.to } else { ty.super_fold_with(self) } - } -} - /// Install projection predicates that allow GATs to project to their own /// definition types. This is not allowed in general in cases of default /// associated types in trait definitions, or when specialization is involved, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 08e0e52a492..d468027602c 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -140,6 +140,10 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) - | sym::fmul_algebraic | sym::fdiv_algebraic | sym::frem_algebraic + | sym::round_ties_even_f16 + | sym::round_ties_even_f32 + | sym::round_ties_even_f64 + | sym::round_ties_even_f128 | sym::const_eval_select => hir::Safety::Safe, _ => hir::Safety::Unsafe, }; @@ -416,26 +420,16 @@ pub fn check_intrinsic_type( sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::rintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::rintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::rintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::rintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::nearbyintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::nearbyintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::nearbyintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::nearbyintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), + sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), + sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), + sym::round_ties_even_f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::roundevenf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::roundevenf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::roundevenf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::roundevenf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::volatile_load | sym::unaligned_volatile_load => { (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)) } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 90e93bdbb50..e1727fc48a8 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; use rustc_middle::bug; -use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; +use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::{Symbol, sym}; @@ -16,10 +16,11 @@ use rustc_target::asm::{ use crate::errors::RegisterTypeUnstable; -pub struct InlineAsmCtxt<'a, 'tcx> { +pub struct InlineAsmCtxt<'a, 'tcx: 'a> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, - get_operand_ty: Box<dyn Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a>, + target_features: &'tcx FxIndexSet<Symbol>, + expr_ty: Box<dyn Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a>, } enum NonAsmTypeReason<'tcx> { @@ -29,25 +30,24 @@ enum NonAsmTypeReason<'tcx> { } impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { - pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self { + pub fn new( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + get_operand_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a, + ) -> Self { InlineAsmCtxt { tcx, typing_env: ty::TypingEnv { typing_mode: ty::TypingMode::non_body_analysis(), param_env: ty::ParamEnv::empty(), }, - get_operand_ty: Box::new(|e| bug!("asm operand in global asm: {e:?}")), + target_features: tcx.asm_target_features(def_id), + expr_ty: Box::new(get_operand_ty), } } - // FIXME(#132279): This likely causes us to incorrectly handle opaque types in their - // defining scope. - pub fn new_in_fn( - tcx: TyCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - get_operand_ty: impl Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a, - ) -> Self { - InlineAsmCtxt { tcx, typing_env, get_operand_ty: Box::new(get_operand_ty) } + fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> { + (self.expr_ty)(expr) } // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()` @@ -139,9 +139,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { template: &[InlineAsmTemplatePiece], is_input: bool, tied_input: Option<(&'tcx hir::Expr<'tcx>, Option<InlineAsmType>)>, - target_features: &FxIndexSet<Symbol>, ) -> Option<InlineAsmType> { - let ty = (self.get_operand_ty)(expr); + let ty = self.expr_ty(expr); if ty.has_non_region_infer() { bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty); } @@ -229,7 +228,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Some((in_expr, Some(in_asm_ty))) = tied_input { if in_asm_ty != asm_ty { let msg = "incompatible types for asm inout argument"; - let in_expr_ty = (self.get_operand_ty)(in_expr); + let in_expr_ty = self.expr_ty(in_expr); self.tcx .dcx() .struct_span_err(vec![in_expr.span, expr.span], msg) @@ -291,7 +290,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // (!). In that case we still need the earlier check to verify that the // register class is usable at all. if let Some(feature) = feature { - if !target_features.contains(feature) { + if !self.target_features.contains(feature) { let msg = format!("`{feature}` target feature is not enabled"); self.tcx .dcx() @@ -351,14 +350,13 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { Some(asm_ty) } - pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, enclosing_id: LocalDefId) { - let target_features = self.tcx.asm_target_features(enclosing_id.to_def_id()); + pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) { let Some(asm_arch) = self.tcx.sess.asm_arch else { self.tcx.dcx().delayed_bug("target architecture does not support asm"); return; }; let allow_experimental_reg = self.tcx.features().asm_experimental_reg(); - for (idx, (op, op_sp)) in asm.operands.iter().enumerate() { + for (idx, &(op, op_sp)) in asm.operands.iter().enumerate() { // Validate register classes against currently enabled target // features. We check that at least one type is available for // the enabled features. @@ -381,12 +379,12 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Err(msg) = reg.validate( asm_arch, self.tcx.sess.relocation_model(), - target_features, + self.target_features, &self.tcx.sess.target, op.is_clobber(), ) { let msg = format!("cannot use register `{}`: {}", reg.name(), msg); - self.tcx.dcx().span_err(*op_sp, msg); + self.tcx.dcx().span_err(op_sp, msg); continue; } } @@ -401,7 +399,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { { match feature { Some(feature) => { - if target_features.contains(&feature) { + if self.target_features.contains(&feature) { missing_required_features.clear(); break; } else { @@ -426,7 +424,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { reg_class.name(), feature ); - self.tcx.dcx().span_err(*op_sp, msg); + self.tcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -440,7 +438,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { .intersperse(", ") .collect::<String>(), ); - self.tcx.dcx().span_err(*op_sp, msg); + self.tcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -448,52 +446,21 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } } - match *op { + match op { hir::InlineAsmOperand::In { reg, expr } => { - self.check_asm_operand_type( - idx, - reg, - expr, - asm.template, - true, - None, - target_features, - ); + self.check_asm_operand_type(idx, reg, expr, asm.template, true, None); } hir::InlineAsmOperand::Out { reg, late: _, expr } => { if let Some(expr) = expr { - self.check_asm_operand_type( - idx, - reg, - expr, - asm.template, - false, - None, - target_features, - ); + self.check_asm_operand_type(idx, reg, expr, asm.template, false, None); } } hir::InlineAsmOperand::InOut { reg, late: _, expr } => { - self.check_asm_operand_type( - idx, - reg, - expr, - asm.template, - false, - None, - target_features, - ); + self.check_asm_operand_type(idx, reg, expr, asm.template, false, None); } hir::InlineAsmOperand::SplitInOut { reg, late: _, in_expr, out_expr } => { - let in_ty = self.check_asm_operand_type( - idx, - reg, - in_expr, - asm.template, - true, - None, - target_features, - ); + let in_ty = + self.check_asm_operand_type(idx, reg, in_expr, asm.template, true, None); if let Some(out_expr) = out_expr { self.check_asm_operand_type( idx, @@ -502,7 +469,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { asm.template, false, Some((in_expr, in_ty)), - target_features, ); } } @@ -514,11 +480,25 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ); } // Typeck has checked that SymFn refers to a function. - hir::InlineAsmOperand::SymFn { anon_const } => { - debug_assert_matches!( - self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(), - ty::Error(_) | ty::FnDef(..) - ); + hir::InlineAsmOperand::SymFn { expr } => { + let ty = self.expr_ty(expr); + match ty.kind() { + ty::FnDef(..) => {} + ty::Error(_) => {} + _ => { + self.tcx + .dcx() + .struct_span_err(op_sp, "invalid `sym` operand") + .with_span_label( + expr.span, + format!("is {} `{}`", ty.kind().article(), ty), + ) + .with_help( + "`sym` operands must refer to either a function or a static", + ) + .emit(); + } + } } // AST lowering guarantees that SymStatic points to a static. hir::InlineAsmOperand::SymStatic { .. } => {} diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 7b3c3ea2bb4..1c5455710db 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -127,7 +127,7 @@ fn get_owner_return_paths( def_id: LocalDefId, ) -> Option<(LocalDefId, ReturnsVisitor<'_>)> { let hir_id = tcx.local_def_id_to_hir_id(def_id); - let parent_id = tcx.hir().get_parent_item(hir_id).def_id; + let parent_id = tcx.hir_get_parent_item(hir_id).def_id; tcx.hir_node_by_def_id(parent_id).body_id().map(|body_id| { let body = tcx.hir_body(body_id); let mut visitor = ReturnsVisitor::default(); diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 88dd40ba289..255f5fee52a 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -844,7 +844,7 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> { fn visit_body(&mut self, body: &hir::Body<'tcx>) { let body_id = body.id(); - let owner_id = self.tcx.hir().body_owner_def_id(body_id); + let owner_id = self.tcx.hir_body_owner_def_id(body_id); debug!( "visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})", @@ -855,7 +855,7 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> { ); self.enter_body(body.value.hir_id, |this| { - if this.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() { + if this.tcx.hir_body_owner_kind(owner_id).is_fn_or_closure() { // The arguments and `self` are parented to the fn. this.cx.var_parent = this.cx.parent.take(); for param in body.params { @@ -924,7 +924,7 @@ pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { return tcx.region_scope_tree(typeck_root_def_id); } - let scope_tree = if let Some(body) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) { + let scope_tree = if let Some(body) = tcx.hir_maybe_body_owned_by(def_id.expect_local()) { let mut visitor = ScopeResolutionVisitor { tcx, scope_tree: ScopeTree::default(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 01b4a5649f1..e6ea6eddcaa 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -16,7 +16,6 @@ use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION; use rustc_macros::LintDiagnostic; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::query::Providers; -use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, @@ -143,33 +142,7 @@ where return Ok(()); } - let is_bevy = 'is_bevy: { - // We don't want to emit this for dependents of Bevy, for now. - // See #119956 - let is_bevy_paramset = |def: ty::AdtDef<'_>| { - let adt_did = with_no_trimmed_paths!(infcx.tcx.def_path_str(def.0.did)); - adt_did.contains("ParamSet") - }; - for ty in assumed_wf_types.iter() { - match ty.kind() { - ty::Adt(def, _) => { - if is_bevy_paramset(*def) { - break 'is_bevy true; - } - } - ty::Ref(_, ty, _) => match ty.kind() { - ty::Adt(def, _) => { - if is_bevy_paramset(*def) { - break 'is_bevy true; - } - } - _ => {} - }, - _ => {} - } - } - false - }; + let is_bevy = assumed_wf_types.visit_with(&mut ContainsBevyParamSet { tcx }).is_break(); // If we have set `no_implied_bounds_compat`, then do not attempt compatibility. // We could also just always enter if `is_bevy`, and call `implied_bounds_tys`, @@ -194,6 +167,31 @@ where } } +struct ContainsBevyParamSet<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsBevyParamSet<'tcx> { + type Result = ControlFlow<()>; + + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + // We only care to match `ParamSet<T>` or `&ParamSet<T>`. + match t.kind() { + ty::Adt(def, _) => { + if self.tcx.item_name(def.did()) == sym::ParamSet + && self.tcx.crate_name(def.did().krate) == sym::bevy_ecs + { + return ControlFlow::Break(()); + } + } + ty::Ref(_, ty, _) => ty.visit_with(self)?, + _ => {} + } + + ControlFlow::Continue(()) + } +} + fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { let node = tcx.hir_node_by_def_id(def_id); let mut res = match node { @@ -855,7 +853,7 @@ fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool { /// In such cases, suggest using `Self` instead. fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { let (trait_name, trait_def_id) = - match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) { + match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(item.hir_id()).def_id) { hir::Node::Item(item) => match item.kind { hir::ItemKind::Trait(..) => (item.ident, item.owner_id), _ => return, @@ -1710,7 +1708,7 @@ fn check_sized_if_body<'tcx>( maybe_span: Option<Span>, ) { let tcx = wfcx.tcx(); - if let Some(body) = tcx.hir().maybe_body_owned_by(def_id) { + if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) { let span = maybe_span.unwrap_or(body.value.span); wfcx.register_bound( diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 68b7b44c36d..750c09887a1 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -13,11 +13,11 @@ pub(crate) fn provide(providers: &mut Providers) { fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { let mut used_trait_imports = UnordSet::<LocalDefId>::default(); - // FIXME: Use `tcx.hir().par_body_owners()` when we implement creating `DefId`s + // FIXME: Use `tcx.hir_par_body_owners()` when we implement creating `DefId`s // for anon constants during their parents' typeck. // Doing so at current will produce queries cycle errors because it may typeck // on anon constants directly. - for item_def_id in tcx.hir().body_owners() { + for item_def_id in tcx.hir_body_owners() { let imports = tcx.used_trait_imports(item_def_id); debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports); used_trait_imports.extend_unord(imports.items().copied()); diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 1805e2438af..c9a9180c5c9 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -113,7 +113,7 @@ impl<'tcx> InherentCollect<'tcx> { ty: Ty<'tcx>, ) -> Result<(), ErrorGuaranteed> { let items = self.tcx.associated_item_def_ids(impl_def_id); - if !self.tcx.hir().rustc_coherence_is_core() { + if !self.tcx.hir_rustc_coherence_is_core() { if self.tcx.features().rustc_attrs() { for &impl_item in items { if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 75ea207a06b..dd91d70b004 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -20,7 +20,6 @@ use std::ops::Bound; use rustc_abi::ExternAbi; use rustc_ast::Recovered; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordMap; use rustc_errors::{ @@ -469,7 +468,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { let item = self .tcx .hir() - .expect_item(self.tcx.hir().get_parent_item(self.hir_id()).def_id); + .expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); match &item.kind { hir::ItemKind::Enum(_, generics) | hir::ItemKind::Struct(_, generics) @@ -680,7 +679,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { | hir::ItemKind::Use(..) | hir::ItemKind::Macro(..) | hir::ItemKind::Mod(_) - | hir::ItemKind::GlobalAsm(_) => {} + | hir::ItemKind::GlobalAsm { .. } => {} hir::ItemKind::ForeignMod { items, .. } => { for item in *items { let item = tcx.hir_foreign_item(item.id); @@ -1349,7 +1348,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn } Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => { - let adt_def_id = tcx.hir().get_parent_item(hir_id).def_id.to_def_id(); + let adt_def_id = tcx.hir_get_parent_item(hir_id).def_id.to_def_id(); let ty = tcx.type_of(adt_def_id).instantiate_identity(); let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity()); // constructors for structs with `layout_scalar_valid_range` are unsafe to call @@ -1690,10 +1689,10 @@ fn polarity_of_impl( /// the lifetimes that are declared. For fns or methods, we have to /// screen out those that do not appear in any where-clauses etc using /// `resolve_lifetime::early_bound_lifetimes`. -fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>( +fn early_bound_lifetimes_from_generics<'a, 'tcx>( tcx: TyCtxt<'tcx>, generics: &'a hir::Generics<'a>, -) -> impl Iterator<Item = &'a hir::GenericParam<'a>> + Captures<'tcx> { +) -> impl Iterator<Item = &'a hir::GenericParam<'a>> { generics.params.iter().filter(move |param| match param.kind { GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id), _ => false, diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index c0902398a54..2cdd9a3a934 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -71,7 +71,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { | Node::Variant(_) | Node::Ctor(..) | Node::Field(_) => { - let parent_id = tcx.hir().get_parent_item(hir_id); + let parent_id = tcx.hir_get_parent_item(hir_id); Some(parent_id.to_def_id()) } // FIXME(#43408) always enable this once `lazy_normalization` is @@ -90,12 +90,12 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { let parent_did = if let DefKind::AnonConst = tcx.def_kind(parent_did) { parent_did } else { - tcx.hir().get_parent_item(hir_id).to_def_id() + tcx.hir_get_parent_item(hir_id).to_def_id() }; debug!(?parent_did); let mut in_param_ty = false; - for (_parent, node) in tcx.hir().parent_iter(hir_id) { + for (_parent, node) in tcx.hir_parent_iter(hir_id) { if let Some(generics) = node.generics() { let mut visitor = AnonConstInParamTyDetector { in_param_ty: false, ct: hir_id }; @@ -189,8 +189,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // Exclude `GlobalAsm` here which cannot have generics. Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => { + hir::InlineAsmOperand::Const { anon_const } => { anon_const.hir_id == hir_id } _ => false, diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 41c4cfbaa82..1c1a246cc15 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -13,7 +13,6 @@ use tracing::{debug, instrument}; use super::ItemCtxt; use super::predicates_of::assert_only_contains_predicates_from; -use crate::bounds::Bounds; use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter}; /// For associated types we include both bounds written on the type @@ -38,7 +37,7 @@ fn associated_type_bounds<'tcx>( ); let icx = ItemCtxt::new(tcx, assoc_item_def_id); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter); // Associated types are implicitly sized unless a `?Sized` bound is found match filter { @@ -68,7 +67,7 @@ fn associated_type_bounds<'tcx>( ) }); - let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent)); + let all_bounds = tcx.arena.alloc_from_iter(bounds.into_iter().chain(bounds_from_parent)); debug!( "associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id.to_def_id()), @@ -327,7 +326,7 @@ fn opaque_type_bounds<'tcx>( ) -> &'tcx [(ty::Clause<'tcx>, Span)] { ty::print::with_reduced_queries!({ let icx = ItemCtxt::new(tcx, opaque_def_id); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter); // Opaque types are implicitly sized unless a `?Sized` bound is found match filter { @@ -343,7 +342,7 @@ fn opaque_type_bounds<'tcx>( } debug!(?bounds); - tcx.arena.alloc_from_iter(bounds.clauses()) + tcx.arena.alloc_slice(&bounds) }) } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index d94383d6f3d..5b511d27074 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -13,7 +13,6 @@ use rustc_span::{DUMMY_SP, Ident, Span}; use tracing::{debug, instrument, trace}; use super::item_bounds::explicit_item_bounds_with_filter; -use crate::bounds::Bounds; use crate::collect::ItemCtxt; use crate::constrained_generic_params as cgp; use crate::delegation::inherit_predicates_for_delegation_item; @@ -178,7 +177,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // on a trait we must also consider the bounds that follow the trait's name, // like `trait Foo: A + B + C`. if let Some(self_bounds) = is_trait { - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds( tcx.types.self_param, self_bounds, @@ -186,7 +185,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ty::List::empty(), PredicateFilter::All, ); - predicates.extend(bounds.clauses()); + predicates.extend(bounds); } // In default impls, we can assume that the self type implements @@ -209,7 +208,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen GenericParamKind::Lifetime { .. } => (), GenericParamKind::Type { .. } => { let param_ty = icx.lowerer().lower_ty_param(param.hir_id); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); // Params are implicitly sized unless a `?Sized` bound is found icx.lowerer().add_sized_bound( &mut bounds, @@ -219,7 +218,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen param.span, ); trace!(?bounds); - predicates.extend(bounds.clauses()); + predicates.extend(bounds); trace!(?predicates); } hir::GenericParamKind::Const { .. } => { @@ -264,7 +263,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } } - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds( ty, bound_pred.bounds, @@ -272,7 +271,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen bound_vars, PredicateFilter::All, ); - predicates.extend(bounds.clauses()); + predicates.extend(bounds); } hir::WherePredicateKind::RegionPredicate(region_pred) => { @@ -383,8 +382,7 @@ fn const_evaluatable_predicates_of<'tcx>( fn is_const_param_default(tcx: TyCtxt<'_>, def: LocalDefId) -> bool { let hir_id = tcx.local_def_id_to_hir_id(def); let (_, parent_node) = tcx - .hir() - .parent_iter(hir_id) + .hir_parent_iter(hir_id) .skip_while(|(_, n)| matches!(n, Node::ConstArg(..))) .next() .unwrap(); @@ -436,7 +434,7 @@ fn const_evaluatable_predicates_of<'tcx>( self_ty.instantiate_identity().visit_with(&mut collector); } - if let Some(_) = tcx.hir().fn_sig_by_hir_id(hir_id) { + if let Some(_) = tcx.hir_fn_sig_by_hir_id(hir_id) { debug!("visit fn sig"); let fn_sig = tcx.fn_sig(def_id); let fn_sig = fn_sig.instantiate_identity(); @@ -627,7 +625,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( let icx = ItemCtxt::new(tcx, trait_def_id); let self_param_ty = tcx.types.self_param; - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter); let where_bounds_that_match = @@ -635,7 +633,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( // Combine the two lists to form the complete set of superbounds: let implied_bounds = - &*tcx.arena.alloc_from_iter(bounds.clauses().chain(where_bounds_that_match)); + &*tcx.arena.alloc_from_iter(bounds.into_iter().chain(where_bounds_that_match)); debug!(?implied_bounds); // Now require that immediate supertraits are lowered, which will, in @@ -826,7 +824,7 @@ pub(super) fn type_param_predicates<'tcx>( // `where T: Foo`. let param_id = tcx.local_def_id_to_hir_id(def_id); - let param_owner = tcx.hir().ty_param_owner(def_id); + let param_owner = tcx.hir_ty_param_owner(def_id); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner { @@ -904,7 +902,7 @@ impl<'tcx> ItemCtxt<'tcx> { param_def_id: LocalDefId, filter: PredicateFilter, ) -> Vec<(ty::Clause<'tcx>, Span)> { - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); for predicate in hir_generics.predicates { let hir_id = predicate.hir_id; @@ -938,7 +936,7 @@ impl<'tcx> ItemCtxt<'tcx> { ); } - bounds.clauses().collect() + bounds } } @@ -1007,7 +1005,7 @@ pub(super) fn const_conditions<'tcx>( }; let icx = ItemCtxt::new(tcx, def_id); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); for pred in generics.predicates { match pred.kind { @@ -1027,12 +1025,12 @@ pub(super) fn const_conditions<'tcx>( } if let Some((def_id, supertraits)) = trait_def_id_and_supertraits { - bounds.push_const_bound( - tcx, - ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())), - ty::BoundConstness::Maybe, + // We've checked above that the trait is conditionally const. + bounds.push(( + ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())) + .to_host_effect_clause(tcx, ty::BoundConstness::Maybe), DUMMY_SP, - ); + )); icx.lowerer().lower_bounds( tcx.types.self_param, @@ -1045,7 +1043,7 @@ pub(super) fn const_conditions<'tcx>( ty::ConstConditions { parent: has_parent.then(|| tcx.local_parent(def_id).to_def_id()), - predicates: tcx.arena.alloc_from_iter(bounds.clauses().map(|(clause, span)| { + predicates: tcx.arena.alloc_from_iter(bounds.into_iter().map(|(clause, span)| { ( clause.kind().map_bound(|clause| match clause { ty::ClauseKind::HostEffect(ty::HostEffectPredicate { diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 5a8a2f1fe28..6b61d317d3f 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -160,7 +160,7 @@ enum Scope<'a> { impl<'a> Scope<'a> { // A helper for debugging scopes without printing parent scopes - fn debug_truncated(&'a self) -> impl fmt::Debug + 'a { + fn debug_truncated(&self) -> impl fmt::Debug { fmt::from_fn(move |f| match self { Self::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f .debug_struct("Binder") @@ -305,21 +305,15 @@ fn generic_param_def_as_bound_arg(param: &ty::GenericParamDef) -> ty::BoundVaria } /// Whether this opaque always captures lifetimes in scope. -/// Right now, this is all RPITIT and TAITs, and when `lifetime_capture_rules_2024` -/// is enabled. We don't check the span of the edition, since this is done -/// on a per-opaque basis to account for nested opaques. -fn opaque_captures_all_in_scope_lifetimes<'tcx>( - tcx: TyCtxt<'tcx>, - opaque: &'tcx hir::OpaqueTy<'tcx>, -) -> bool { +/// Right now, this is all RPITIT and TAITs, and when the opaque +/// is coming from a span corresponding to edition 2024. +fn opaque_captures_all_in_scope_lifetimes<'tcx>(opaque: &'tcx hir::OpaqueTy<'tcx>) -> bool { match opaque.origin { // if the opaque has the `use<...>` syntax, the user is telling us that they only want // to account for those lifetimes, so do not try to be clever. _ if opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..))) => false, hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => true, - _ if tcx.features().lifetime_capture_rules_2024() || opaque.span.at_least_rust_2024() => { - true - } + _ if opaque.span.at_least_rust_2024() => true, hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => in_trait_or_impl.is_some(), } } @@ -519,8 +513,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { fn visit_opaque_ty(&mut self, opaque: &'tcx rustc_hir::OpaqueTy<'tcx>) { let captures = RefCell::new(FxIndexMap::default()); - let capture_all_in_scope_lifetimes = - opaque_captures_all_in_scope_lifetimes(self.tcx, opaque); + let capture_all_in_scope_lifetimes = opaque_captures_all_in_scope_lifetimes(opaque); if capture_all_in_scope_lifetimes { let lifetime_ident = |def_id: LocalDefId| { let name = self.tcx.item_name(def_id.to_def_id()); @@ -630,7 +623,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } | hir::ItemKind::Static(..) - | hir::ItemKind::GlobalAsm(..) => { + | hir::ItemKind::GlobalAsm { .. } => { // These sorts of items have no lifetime parameters at all. intravisit::walk_item(self, item); } @@ -1340,7 +1333,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { }; def = ResolvedArg::Error(guar); } else if let Some(body_id) = outermost_body { - let fn_id = self.tcx.hir().body_owner(body_id); + let fn_id = self.tcx.hir_body_owner(body_id); match self.tcx.hir_node(fn_id) { Node::Item(hir::Item { owner_id, kind: hir::ItemKind::Fn { .. }, .. }) | Node::TraitItem(hir::TraitItem { @@ -2166,10 +2159,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { /// Walk the generics of the item for a trait bound whose self type /// corresponds to the expected res, and return the trait def id. - fn for_each_trait_bound_on_res( - &self, - expected_res: Res, - ) -> impl Iterator<Item = DefId> + use<'tcx, '_> { + fn for_each_trait_bound_on_res(&self, expected_res: Res) -> impl Iterator<Item = DefId> { std::iter::from_coroutine( #[coroutine] move || { @@ -2265,7 +2255,7 @@ fn is_late_bound_map( tcx: TyCtxt<'_>, owner_id: hir::OwnerId, ) -> Option<&FxIndexSet<hir::ItemLocalId>> { - let sig = tcx.hir().fn_sig_by_hir_id(owner_id.into())?; + let sig = tcx.hir_fn_sig_by_hir_id(owner_id.into())?; let generics = tcx.hir_get_generics(owner_id.def_id)?; let mut late_bound = FxIndexSet::default(); @@ -2276,7 +2266,7 @@ fn is_late_bound_map( } let mut appears_in_output = - AllCollector { tcx, has_fully_capturing_opaque: false, regions: Default::default() }; + AllCollector { has_fully_capturing_opaque: false, regions: Default::default() }; intravisit::walk_fn_ret_ty(&mut appears_in_output, &sig.decl.output); if appears_in_output.has_fully_capturing_opaque { appears_in_output.regions.extend(generics.params.iter().map(|param| param.def_id)); @@ -2289,7 +2279,7 @@ fn is_late_bound_map( // Subtle point: because we disallow nested bindings, we can just // ignore binders here and scrape up all names we see. let mut appears_in_where_clause = - AllCollector { tcx, has_fully_capturing_opaque: true, regions: Default::default() }; + AllCollector { has_fully_capturing_opaque: true, regions: Default::default() }; appears_in_where_clause.visit_generics(generics); debug!(?appears_in_where_clause.regions); @@ -2455,23 +2445,21 @@ fn is_late_bound_map( } } - struct AllCollector<'tcx> { - tcx: TyCtxt<'tcx>, + struct AllCollector { has_fully_capturing_opaque: bool, regions: FxHashSet<LocalDefId>, } - impl<'v> Visitor<'v> for AllCollector<'v> { - fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { + impl<'tcx> Visitor<'tcx> for AllCollector { + fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { if let hir::LifetimeName::Param(def_id) = lifetime_ref.res { self.regions.insert(def_id); } } - fn visit_opaque_ty(&mut self, opaque: &'v hir::OpaqueTy<'v>) { + fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) { if !self.has_fully_capturing_opaque { - self.has_fully_capturing_opaque = - opaque_captures_all_in_scope_lifetimes(self.tcx, opaque); + self.has_fully_capturing_opaque = opaque_captures_all_in_scope_lifetimes(opaque); } intravisit::walk_opaque_ty(self, opaque); } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 293a095b41d..d564dc9699a 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -35,13 +35,6 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx let parent_node_id = tcx.parent_hir_id(hir_id); let parent_node = tcx.hir_node(parent_node_id); - let find_sym_fn = |&(op, op_sp)| match op { - hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == hir_id => { - Some((anon_const, op_sp)) - } - _ => None, - }; - let find_const = |&(op, op_sp)| match op { hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == hir_id => { Some((anon_const, op_sp)) @@ -59,31 +52,7 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx // Anon consts outside the type system. Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) - if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_sym_fn) => - { - let ty = tcx.typeck(def_id).node_type(hir_id); - - match ty.kind() { - ty::Error(_) => ty, - ty::FnDef(..) => ty, - _ => { - let guar = tcx - .dcx() - .struct_span_err(op_sp, "invalid `sym` operand") - .with_span_label( - tcx.def_span(anon_const.def_id), - format!("is {} `{}`", ty.kind().article(), ty), - ) - .with_help("`sym` operands must refer to either a function or a static") - .emit(); - - Ty::new_error(tcx, guar) - } - } - } - Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) + | Node::Item(&Item { kind: ItemKind::GlobalAsm { asm, .. }, .. }) if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_const) => { let ty = tcx.typeck(def_id).node_type(hir_id); @@ -106,8 +75,8 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx } } } - Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { - tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) + Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => { + tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) } // Sort of affects the type system, but only for the purpose of diagnostics // so no need for ConstArg. @@ -257,7 +226,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } } ImplItemKind::Type(ty) => { - if tcx.impl_trait_ref(tcx.hir().get_parent_item(hir_id)).is_none() { + if tcx.impl_trait_ref(tcx.hir_get_parent_item(hir_id)).is_none() { check_feature_inherent_assoc_ty(tcx, item.span); } @@ -313,12 +282,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_adt(tcx, def, args) } + ItemKind::GlobalAsm { .. } => tcx.typeck(def_id).node_type(hir_id), ItemKind::Trait(..) | ItemKind::TraitAlias(..) | ItemKind::Macro(..) | ItemKind::Mod(..) | ItemKind::ForeignMod { .. } - | ItemKind::GlobalAsm(..) | ItemKind::ExternCrate(..) | ItemKind::Use(..) => { span_bug!(item.span, "compute_type_of_item: unexpected item type: {:?}", item.kind); @@ -341,7 +310,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def { VariantData::Unit(..) | VariantData::Struct { .. } => { - tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity() + tcx.type_of(tcx.hir_get_parent_item(hir_id)).instantiate_identity() } VariantData::Tuple(_, _, ctor) => { let args = ty::GenericArgs::identity_for_item(tcx, def_id); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 88d4acbdd8d..399c4fbe55a 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -83,13 +83,13 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( #[instrument(skip(tcx), level = "debug")] pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { let hir_id = tcx.local_def_id_to_hir_id(def_id); - let scope = tcx.hir().get_defining_scope(hir_id); + let scope = tcx.hir_get_defining_scope(hir_id); let mut locator = TaitConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] }; debug!(?scope); if scope == hir::CRATE_HIR_ID { - tcx.hir().walk_toplevel_module(&mut locator); + tcx.hir_walk_toplevel_module(&mut locator); } else { trace!("scope={:#?}", tcx.hir_node(scope)); match tcx.hir_node(scope) { diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 14ea10461cb..1a0b0edb257 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1417,6 +1417,15 @@ pub(crate) struct CrossCrateTraitsDefined { pub traits: String, } +#[derive(Diagnostic)] +#[diag(hir_analysis_no_variant_named, code = E0599)] +pub struct NoVariantNamed<'tcx> { + #[primary_span] + pub span: Span, + pub ident: Ident, + pub ty: Ty<'tcx>, +} + // FIXME(fmease): Deduplicate: #[derive(Diagnostic)] diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 681e8e36d58..610b293a114 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -134,9 +134,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { // is from the 'of_trait' field of the enclosing impl let parent = self.tcx.parent_hir_node(self.path_segment.hir_id); - let parent_item = self.tcx.hir_node_by_def_id( - self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id, - ); + let parent_item = self + .tcx + .hir_node_by_def_id(self.tcx.hir_get_parent_item(self.path_segment.hir_id).def_id); // Get the HIR id of the trait ref let hir::Node::TraitRef(hir::TraitRef { hir_ref_id: trait_ref_id, .. }) = parent else { @@ -343,7 +343,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let mut ret = Vec::new(); let mut ty_id = None; - for (id, node) in self.tcx.hir().parent_iter(path_hir_id) { + for (id, node) in self.tcx.hir_parent_iter(path_hir_id) { debug!(?id); if let hir::Node::Ty(_) = node { ty_id = Some(id); @@ -437,8 +437,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { ) -> String { let is_in_a_method_call = self .tcx - .hir() - .parent_iter(self.path_segment.hir_id) + .hir_parent_iter(self.path_segment.hir_id) .skip(1) .find_map(|(_, node)| match node { hir::Node::Expr(expr) => Some(expr), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index ef6167907b5..dd346ed1f97 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -8,7 +8,7 @@ use rustc_hir::HirId; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::bug; -use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt}; +use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt, Upcast}; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym}; use rustc_trait_selection::traits; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; @@ -16,7 +16,6 @@ use smallvec::SmallVec; use tracing::{debug, instrument}; use super::errors::GenericsArgsErrExtend; -use crate::bounds::Bounds; use crate::errors; use crate::hir_ty_lowering::{ AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason, @@ -28,7 +27,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`. pub(crate) fn add_sized_bound( &self, - bounds: &mut Bounds<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, hir_bounds: &'tcx [hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, @@ -113,10 +112,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound { // There was in fact a `?Sized`, `!Sized` or explicit `Sized` bound; // we don't need to do anything. - } else if sized_def_id.is_some() { + } else if let Some(sized_def_id) = sized_def_id { // There was no `?Sized`, `!Sized` or explicit `Sized` bound; // add `Sized` if it's available. - bounds.push_sized(tcx, self_ty, span); + let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [self_ty]); + // Preferable to put this obligation first, since we report better errors for sized ambiguity. + bounds.insert(0, (trait_ref.upcast(tcx), span)); } } @@ -146,7 +147,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, param_ty: Ty<'tcx>, hir_bounds: I, - bounds: &mut Bounds<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, bound_vars: &'tcx ty::List<ty::BoundVariableKind>, predicate_filter: PredicateFilter, ) where @@ -189,14 +190,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound); - bounds.push_region_bound( - self.tcx(), - ty::Binder::bind_with_vars( - ty::OutlivesPredicate(param_ty, region), - bound_vars, - ), - lifetime.ident.span, + let bound = ty::Binder::bind_with_vars( + ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(param_ty, region)), + bound_vars, ); + bounds.push((bound.upcast(self.tcx()), lifetime.ident.span)); } hir::GenericBound::Use(..) => { // We don't actually lower `use` into the type layer. @@ -219,7 +217,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_ref_id: hir::HirId, trait_ref: ty::PolyTraitRef<'tcx>, constraint: &hir::AssocItemConstraint<'tcx>, - bounds: &mut Bounds<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, duplicates: &mut FxIndexMap<DefId, Span>, path_span: Span, predicate_filter: PredicateFilter, @@ -389,14 +387,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { PredicateFilter::All | PredicateFilter::SelfOnly | PredicateFilter::SelfAndAssociatedTypeBounds => { - bounds.push_projection_bound( - tcx, - projection_term.map_bound(|projection_term| ty::ProjectionPredicate { + let bound = projection_term.map_bound(|projection_term| { + ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_term, term, - }), - constraint.span, - ); + }) + }); + bounds.push((bound.upcast(tcx), constraint.span)); } // SelfTraitThatDefines is only interested in trait predicates. PredicateFilter::SelfTraitThatDefines(_) => {} @@ -739,8 +736,7 @@ fn check_assoc_const_binding_type<'tcx>( .map(|ty| crate::errors::TyOfAssocConstBindingNote { assoc_const, ty }); let enclosing_item_owner_id = tcx - .hir() - .parent_owner_iter(hir_id) + .hir_parent_owner_iter(hir_id) .find_map(|(owner_id, parent)| parent.generics().map(|_| owner_id)) .unwrap(); let generics = tcx.generics_of(enclosing_item_owner_id); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index a8b37fa5054..3eb4945ebf8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; @@ -17,7 +17,6 @@ use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; use super::HirTyLowerer; -use crate::bounds::Bounds; use crate::hir_ty_lowering::{ GenericArgCountMismatch, GenericArgCountResult, PredicateFilter, RegionInferReason, }; @@ -36,7 +35,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); let dummy_self = tcx.types.trait_object_dummy_self; - let mut user_written_bounds = Bounds::default(); + let mut user_written_bounds = Vec::new(); let mut potential_assoc_types = Vec::new(); for trait_bound in hir_bounds.iter() { if let hir::BoundPolarity::Maybe(_) = trait_bound.modifiers.polarity { @@ -59,16 +58,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - let (trait_bounds, mut projection_bounds) = - traits::expand_trait_aliases(tcx, user_written_bounds.clauses()); - let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = trait_bounds + let (elaborated_trait_bounds, elaborated_projection_bounds) = + traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied()); + let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = elaborated_trait_bounds .into_iter() .partition(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id())); // We don't support empty trait objects. if regular_traits.is_empty() && auto_traits.is_empty() { - let guar = - self.report_trait_object_with_no_traits_error(span, user_written_bounds.clauses()); + let guar = self.report_trait_object_with_no_traits_error( + span, + user_written_bounds.iter().copied(), + ); return Ty::new_error(tcx, guar); } // We don't support >1 principal @@ -84,7 +85,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Check that there are no gross dyn-compatibility violations; // most importantly, that the supertraits don't contain `Self`, // to avoid ICEs. - for (clause, span) in user_written_bounds.clauses() { + for (clause, span) in user_written_bounds { if let Some(trait_pred) = clause.as_trait_clause() { let violations = hir_ty_lowering_dyn_compatibility_violations(tcx, trait_pred.def_id()); @@ -102,29 +103,81 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + // Map the projection bounds onto a key that makes it easy to remove redundant + // bounds that are constrained by supertraits of the principal def id. + // + // Also make sure we detect conflicting bounds from expanding a trait alias and + // also specifying it manually, like: + // ``` + // type Alias = Trait<Assoc = i32>; + // let _: &dyn Alias<Assoc = u32> = /* ... */; + // ``` + let mut projection_bounds = FxIndexMap::default(); + for (proj, proj_span) in elaborated_projection_bounds { + let key = ( + proj.skip_binder().projection_term.def_id, + tcx.anonymize_bound_vars( + proj.map_bound(|proj| proj.projection_term.trait_ref(tcx)), + ), + ); + if let Some((old_proj, old_proj_span)) = + projection_bounds.insert(key, (proj, proj_span)) + && tcx.anonymize_bound_vars(proj) != tcx.anonymize_bound_vars(old_proj) + { + let item = tcx.item_name(proj.item_def_id()); + self.dcx() + .struct_span_err( + span, + format!( + "conflicting associated type bounds for `{item}` when \ + expanding trait alias" + ), + ) + .with_span_label( + old_proj_span, + format!("`{item}` is specified to be `{}` here", old_proj.term()), + ) + .with_span_label( + proj_span, + format!("`{item}` is specified to be `{}` here", proj.term()), + ) + .emit(); + } + } + let principal_trait = regular_traits.into_iter().next(); - let mut needed_associated_types = FxIndexSet::default(); - if let Some((principal_trait, spans)) = &principal_trait { - let pred: ty::Predicate<'tcx> = (*principal_trait).upcast(tcx); - for ClauseWithSupertraitSpan { pred, supertrait_span } in traits::elaborate( + let mut needed_associated_types = vec![]; + if let Some((principal_trait, ref spans)) = principal_trait { + let principal_trait = principal_trait.map_bound(|trait_pred| { + assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive); + trait_pred.trait_ref + }); + + for ClauseWithSupertraitSpan { clause, supertrait_span } in traits::elaborate( tcx, - [ClauseWithSupertraitSpan::new(pred, *spans.last().unwrap())], + [ClauseWithSupertraitSpan::new( + ty::TraitRef::identity(tcx, principal_trait.def_id()).upcast(tcx), + *spans.last().unwrap(), + )], ) .filter_only_self() { - debug!("observing object predicate `{pred:?}`"); + let clause = clause.instantiate_supertrait(tcx, principal_trait); + debug!("observing object predicate `{clause:?}`"); - let bound_predicate = pred.kind(); + let bound_predicate = clause.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { + ty::ClauseKind::Trait(pred) => { // FIXME(negative_bounds): Handle this correctly... let trait_ref = tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref)); needed_associated_types.extend( - tcx.associated_items(trait_ref.def_id()) + tcx.associated_items(pred.trait_ref.def_id) .in_definition_order() + // We only care about associated types. .filter(|item| item.kind == ty::AssocKind::Type) + // No RPITITs -- even with `async_fn_in_dyn_trait`, they are implicit. .filter(|item| !item.is_impl_trait_in_trait()) // If the associated type has a `where Self: Sized` bound, // we do not need to constrain the associated type. @@ -132,7 +185,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .map(|item| (item.def_id, trait_ref)), ); } - ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => { + ty::ClauseKind::Projection(pred) => { let pred = bound_predicate.rebind(pred); // A `Self` within the original bound will be instantiated with a // `trait_object_dummy_self`, so check for that. @@ -160,8 +213,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `dyn MyTrait<MyOutput = X, Output = X>`, which is uglier but works. See // the discussion in #56288 for alternatives. if !references_self { - // Include projections defined on supertraits. - projection_bounds.push((pred, supertrait_span)); + let key = ( + pred.skip_binder().projection_term.def_id, + tcx.anonymize_bound_vars( + pred.map_bound(|proj| proj.projection_term.trait_ref(tcx)), + ), + ); + if !projection_bounds.contains_key(&key) { + projection_bounds.insert(key, (pred, supertrait_span)); + } } self.check_elaborated_projection_mentions_input_lifetimes( @@ -181,12 +241,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // types that we expect to be provided by the user, so the following loop // removes all the associated types that have a corresponding `Projection` // clause, either from expanding trait aliases or written by the user. - for &(projection_bound, span) in &projection_bounds { + for &(projection_bound, span) in projection_bounds.values() { let def_id = projection_bound.item_def_id(); - let trait_ref = tcx.anonymize_bound_vars( - projection_bound.map_bound(|p| p.projection_term.trait_ref(tcx)), - ); - needed_associated_types.swap_remove(&(def_id, trait_ref)); if tcx.generics_require_sized_self(def_id) { tcx.emit_node_span_lint( UNUSED_ASSOCIATED_TYPE_BOUNDS, @@ -197,9 +253,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + let mut missing_assoc_types = FxIndexSet::default(); + let projection_bounds: Vec<_> = needed_associated_types + .into_iter() + .filter_map(|key| { + if let Some(assoc) = projection_bounds.get(&key) { + Some(*assoc) + } else { + missing_assoc_types.insert(key); + None + } + }) + .collect(); + if let Err(guar) = self.check_for_required_assoc_tys( principal_trait.as_ref().map_or(smallvec![], |(_, spans)| spans.clone()), - needed_associated_types, + missing_assoc_types, potential_assoc_types, hir_bounds, ) { @@ -265,7 +334,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) }); - let existential_projections = projection_bounds.iter().map(|(bound, _)| { + let existential_projections = projection_bounds.into_iter().map(|(bound, _)| { bound.map_bound(|mut b| { assert_eq!(b.projection_term.self_ty(), dummy_self); @@ -290,12 +359,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) }); - let auto_trait_predicates = auto_traits.into_iter().map(|(trait_pred, _)| { - assert_eq!(trait_pred.polarity(), ty::PredicatePolarity::Positive); - assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self); + let mut auto_trait_predicates: Vec<_> = auto_traits + .into_iter() + .map(|(trait_pred, _)| { + assert_eq!(trait_pred.polarity(), ty::PredicatePolarity::Positive); + assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self); - ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id())) - }); + ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id())) + }) + .collect(); + auto_trait_predicates.dedup(); // N.b. principal, projections, auto traits // FIXME: This is actually wrong with multiple principals in regards to symbol mangling @@ -305,7 +378,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .chain(auto_trait_predicates) .collect::<SmallVec<[_; 8]>>(); v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); - v.dedup(); let existential_predicates = tcx.mk_poly_existential_predicates(&v); // Use explicitly-specified region bound, unless the bound is missing. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index d2789cc0fd6..d644a1f224c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -223,7 +223,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // inside an opaque type while we're interested in the overarching type alias (TAIT). // FIXME: However, for trait aliases, this incorrectly returns the enclosing module... && let item_def_id = - tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(ty_param_def_id)) + tcx.hir_get_parent_item(tcx.local_def_id_to_hir_id(ty_param_def_id)) // FIXME: ...which obviously won't have any generics. && let Some(generics) = tcx.hir_get_generics(item_def_id.def_id) { @@ -979,7 +979,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { qself: &hir::Ty<'_>, ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); - if let Some((_, node)) = tcx.hir().parent_iter(qself.hir_id).skip(1).next() + if let Some((_, node)) = tcx.hir_parent_iter(qself.hir_id).skip(1).next() && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Path(hir::QPath::TypeRelative( @@ -1278,8 +1278,7 @@ pub fn prohibit_assoc_item_constraint( // Get the parent impl block based on the binding we have // and the trait DefId let impl_block = tcx - .hir() - .parent_iter(constraint.hir_id) + .hir_parent_iter(constraint.hir_id) .find_map(|(_, node)| node.impl_block_of_trait(def_id)); let type_with_constraints = diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index cc28b8780c6..8d58a3bfbd3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -70,7 +70,7 @@ fn generic_arg_mismatch_err( } Res::Def(DefKind::TyParam, src_def_id) => { if let Some(param_local_id) = param.def_id.as_local() { - let param_name = tcx.hir().ty_param_name(param_local_id); + let param_name = tcx.hir_ty_param_name(param_local_id); let param_type = tcx.type_of(param.def_id).instantiate_identity(); if param_type.is_suggestable(tcx, false) { err.span_suggestion( @@ -542,8 +542,7 @@ pub(crate) fn check_generic_arg_count( // ``` let parent_is_impl_block = cx .tcx() - .hir() - .parent_owner_iter(seg.hir_id) + .hir_parent_owner_iter(seg.hir_id) .next() .is_some_and(|(_, owner_node)| owner_node.is_impl_block()); if parent_is_impl_block { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 44f7a035a10..f5e075367f3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -130,7 +130,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { diag: &mut Diag<'_, G>, ) { let tcx = self.tcx(); - let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id; + let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { self_ty: impl_self_ty, of_trait, generics, .. }), .. @@ -191,7 +191,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Make sure that we are in the condition to suggest `impl Trait`. fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) -> bool { let tcx = self.tcx(); - let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id; + let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; // FIXME: If `type_alias_impl_trait` is enabled, also look for `Trait0<Ty = Trait1>` // and suggest `Trait0<Ty = impl Trait1>`. // Functions are found in three different contexts. @@ -321,7 +321,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) { - let mut parents = self.tcx().hir().parent_iter(self_ty.hir_id); + let mut parents = self.tcx().hir_parent_iter(self_ty.hir_id); if let Some((_, hir::Node::AssocItemConstraint(constraint))) = parents.next() && let Some(obj_ty) = constraint.ty() diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index d5ccbdc11c8..750770178ee 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -49,11 +49,13 @@ use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::wf::object_region_bounds; use rustc_trait_selection::traits::{self, ObligationCtxt}; +use rustc_type_ir::Upcast; use tracing::{debug, instrument}; -use crate::bounds::Bounds; use crate::check::check_abi_fn_ptr; -use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType}; +use crate::errors::{ + AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, NoVariantNamed, +}; use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint}; use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args}; use crate::middle::resolve_bound_vars as rbv; @@ -217,7 +219,7 @@ impl AssocItemQSelf { fn to_string(&self, tcx: TyCtxt<'_>) -> String { match *self { Self::Trait(def_id) => tcx.def_path_str(def_id), - Self::TyParam(def_id, _) => tcx.hir().ty_param_name(def_id).to_string(), + Self::TyParam(def_id, _) => tcx.hir_ty_param_name(def_id).to_string(), Self::SelfTyAlias => kw::SelfUpper.to_string(), } } @@ -342,8 +344,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } rbv::ResolvedArg::EarlyBound(def_id) => { - let name = tcx.hir().ty_param_name(def_id); - let item_def_id = tcx.hir().ty_param_owner(def_id); + let name = tcx.hir_ty_param_name(def_id); + let item_def_id = tcx.hir_ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name }) @@ -691,7 +693,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { constness: hir::BoundConstness, polarity: hir::BoundPolarity, self_ty: Ty<'tcx>, - bounds: &mut Bounds<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, predicate_filter: PredicateFilter, ) -> GenericArgCountResult { let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); @@ -720,6 +722,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bound_vars, ); + debug!(?poly_trait_ref); + let polarity = match polarity { rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, @@ -741,6 +745,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } }; + // We deal with const conditions later. + match predicate_filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfTraitThatDefines(..) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + let bound = poly_trait_ref.map_bound(|trait_ref| { + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity }) + }); + let bound = (bound.upcast(tcx), span); + // FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands. + if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) { + bounds.insert(0, bound); + } else { + bounds.push(bound); + } + } + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} + } + if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness && !self.tcx().is_const_trait(trait_def_id) { @@ -765,58 +789,53 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { suggestion_pre, suggestion, }); - } - - match predicate_filter { - // This is only concerned with trait predicates. - PredicateFilter::SelfTraitThatDefines(..) => { - bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); - } - PredicateFilter::All - | PredicateFilter::SelfOnly - | PredicateFilter::SelfAndAssociatedTypeBounds => { - debug!(?poly_trait_ref); - bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); - - match constness { - hir::BoundConstness::Always(span) => { - if polarity == ty::PredicatePolarity::Positive { - bounds.push_const_bound( - tcx, - poly_trait_ref, - ty::BoundConstness::Const, - span, - ); + } else { + match predicate_filter { + // This is only concerned with trait predicates. + PredicateFilter::SelfTraitThatDefines(..) => {} + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfAndAssociatedTypeBounds => { + match constness { + hir::BoundConstness::Always(span) => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push(( + poly_trait_ref + .to_host_effect_clause(tcx, ty::BoundConstness::Const), + span, + )); + } } + hir::BoundConstness::Maybe(_) => { + // We don't emit a const bound here, since that would mean that we + // unconditionally need to prove a `HostEffect` predicate, even when + // the predicates are being instantiated in a non-const context. This + // is instead handled in the `const_conditions` query. + } + hir::BoundConstness::Never => {} } - hir::BoundConstness::Maybe(_) => { - // We don't emit a const bound here, since that would mean that we - // unconditionally need to prove a `HostEffect` predicate, even when - // the predicates are being instantiated in a non-const context. This - // is instead handled in the `const_conditions` query. - } - hir::BoundConstness::Never => {} } - } - // On the flip side, when filtering `ConstIfConst` bounds, we only need to convert - // `~const` bounds. All other predicates are handled in their respective queries. - // - // Note that like `PredicateFilter::SelfOnly`, we don't need to do any filtering - // here because we only call this on self bounds, and deal with the recursive case - // in `lower_assoc_item_constraint`. - PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness { - hir::BoundConstness::Maybe(span) => { - if polarity == ty::PredicatePolarity::Positive { - bounds.push_const_bound( - tcx, - poly_trait_ref, - ty::BoundConstness::Maybe, - span, - ); + // On the flip side, when filtering `ConstIfConst` bounds, we only need to convert + // `~const` bounds. All other predicates are handled in their respective queries. + // + // Note that like `PredicateFilter::SelfOnly`, we don't need to do any filtering + // here because we only call this on self bounds, and deal with the recursive case + // in `lower_assoc_item_constraint`. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => { + match constness { + hir::BoundConstness::Maybe(span) => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push(( + poly_trait_ref + .to_host_effect_clause(tcx, ty::BoundConstness::Maybe), + span, + )); + } + } + hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {} } } - hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {} - }, + } } let mut dup_constraints = FxIndexMap::default(); @@ -1188,14 +1207,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let msg = format!("expected type, found variant `{assoc_ident}`"); self.dcx().span_err(span, msg) } else if qself_ty.is_enum() { - let mut err = struct_span_code_err!( - self.dcx(), - assoc_ident.span, - E0599, - "no variant named `{}` found for enum `{}`", - assoc_ident, - qself_ty, - ); + let mut err = self.dcx().create_err(NoVariantNamed { + span: assoc_ident.span, + ident: assoc_ident, + ty: qself_ty, + }); let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT"); if let Some(variant_name) = find_best_match_for_name( @@ -1210,11 +1226,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { adt_def.variants().iter().find(|s| s.name == variant_name) { let mut suggestion = vec![(assoc_ident.span, variant_name.to_string())]; - if let hir::Node::Stmt(hir::Stmt { - kind: hir::StmtKind::Semi(ref expr), - .. + if let hir::Node::Stmt(&hir::Stmt { + kind: hir::StmtKind::Semi(expr), .. }) - | hir::Node::Expr(ref expr) = tcx.parent_hir_node(hir_ref_id) + | hir::Node::Expr(expr) = tcx.parent_hir_node(hir_ref_id) && let hir::ExprKind::Struct(..) = expr.kind { match variant.ctor { @@ -1657,8 +1672,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(item_def_id = ?def_id); // FIXME: document why/how this is different from `tcx.local_parent(def_id)` - let parent_def_id = - tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id(); + let parent_def_id = tcx.hir_get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id(); debug!(?parent_def_id); // If the trait in segment is the same as the trait defining the item, @@ -2053,10 +2067,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Ty::new_bound(tcx, debruijn, br) } Some(rbv::ResolvedArg::EarlyBound(def_id)) => { - let item_def_id = tcx.hir().ty_param_owner(def_id); + let item_def_id = tcx.hir_ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id)) + Ty::new_param(tcx, index, tcx.hir_ty_param_name(def_id)) } Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar), arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), @@ -2382,7 +2396,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Impl trait in bindings lower as an infer var with additional // set of type bounds. let self_ty = self.ty_infer(None, hir_ty.span); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); self.lower_bounds( self_ty, hir_bounds.iter(), @@ -2390,11 +2404,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::List::empty(), PredicateFilter::All, ); - self.register_trait_ascription_bounds( - bounds.clauses().collect(), - hir_ty.hir_id, - hir_ty.span, - ); + self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span); self_ty } // If we encounter a type relative path with RTN generics, then it must have diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index f5abcd23440..0b1be8e4f7a 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -22,8 +22,6 @@ fn diagnostic_hir_wf_check<'tcx>( tcx: TyCtxt<'tcx>, (predicate, loc): (ty::Predicate<'tcx>, WellFormedLoc), ) -> Option<ObligationCause<'tcx>> { - let hir = tcx.hir(); - let def_id = match loc { WellFormedLoc::Ty(def_id) => def_id, WellFormedLoc::Param { function, param_idx: _ } => function, @@ -187,7 +185,7 @@ fn diagnostic_hir_wf_check<'tcx>( ref node => bug!("Unexpected node {:?}", node), }, WellFormedLoc::Param { function: _, param_idx } => { - let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap(); + let fn_decl = tcx.hir_fn_decl_by_hir_id(hir_id).unwrap(); // Get return type if param_idx as usize == fn_decl.inputs.len() { match fn_decl.output { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 8a529e9c686..bdfbd540e40 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -80,7 +80,6 @@ This API is completely unstable and subject to change. pub mod check; pub mod autoderef; -mod bounds; mod check_unused; mod coherence; mod collect; @@ -93,6 +92,7 @@ mod impl_wf_check; mod outlives; mod variance; +pub use errors::NoVariantNamed; use rustc_abi::ExternAbi; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -184,7 +184,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // what we are intending to discard, to help future type-based refactoring. type R = Result<(), ErrorGuaranteed>; - tcx.hir().par_for_each_module(|module| { + tcx.par_hir_for_each_module(|module| { let _: R = tcx.ensure_ok().check_mod_type_wf(module); }); @@ -209,7 +209,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // Make sure we evaluate all static and (non-associated) const items, even if unused. // If any of these fail to evaluate, we do not want this crate to pass compilation. - tcx.hir().par_body_owners(|item_def_id| { + tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); match def_kind { DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id), @@ -227,7 +227,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // for anon constants during their parents' typeck. // Typeck all body owners in parallel will produce queries // cycle errors because it may typeck on anon constants directly. - tcx.hir().par_body_owners(|item_def_id| { + tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); if !matches!(def_kind, DefKind::AnonConst) { tcx.ensure_ok().typeck(item_def_id); @@ -251,7 +251,7 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { // In case there are any projections, etc., find the "environment" // def-ID that will be used to determine the traits/predicates in // scope. This is derived from the enclosing item-like thing. - let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id); + let env_def_id = tcx.hir_get_parent_item(hir_ty.hir_id); collect::ItemCtxt::new(tcx, env_def_id.def_id).lower_ty(hir_ty) } @@ -262,6 +262,6 @@ pub fn lower_const_arg_for_rustdoc<'tcx>( hir_ct: &hir::ConstArg<'tcx>, feed: FeedConstTy, ) -> Const<'tcx> { - let env_def_id = tcx.hir().get_parent_item(hir_ct.hir_id); + let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id); collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed) } diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index c43917649de..32b05dcc569 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -37,7 +37,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau // parent of generics returned by `generics_of` // // In the above code we want the anon const to have predicates in its param env for `'b: 'a` - let item_def_id = tcx.hir().get_parent_item(id); + let item_def_id = tcx.hir_get_parent_item(id); // In the above code example we would be calling `inferred_outlives_of(Foo)` here tcx.inferred_outlives_of(item_def_id) } else { |
