diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 1b73758200939..078b676e40ebf 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -5,7 +5,6 @@ #![cfg_attr(feature = "nightly", feature(rustc_attrs))] #![cfg_attr(feature = "nightly", feature(rustdoc_internals))] #![cfg_attr(feature = "nightly", feature(step_trait))] -#![warn(unreachable_pub)] // tidy-alphabetical-end /*! ABI handling for rustc diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 3b44e99635810..6aaac072e4b28 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -23,7 +23,6 @@ #![feature(maybe_uninit_slice)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::alloc::Layout; diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 6372c66050e7c..294c6c9ba7a50 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -19,7 +19,6 @@ #![feature(never_type)] #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod util { diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index 9884e191ea7bd..6d05cd18cec12 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -9,7 +9,6 @@ #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(never_type))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] -#![warn(unreachable_pub)] // tidy-alphabetical-end #[cfg(feature = "nightly")] diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 571172be4ed16..946f2cafa15f2 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -330,6 +330,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .unwrap_or_default() && delegation.qself.is_none() && !has_generic_args + && !args.is_empty() { let ast_segment = delegation.path.segments.last().unwrap(); let segment = self.lower_path_segment( diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1bf85bbf26c95..e5569458dbdeb 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -39,7 +39,6 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::sync::Arc; diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index b4ed70d83e570..093199cf34212 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -10,7 +10,6 @@ #![feature(iter_is_partitioned)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod ast_validation; diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 602ab69ee5b5d..84d9ce278a21a 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -3,7 +3,6 @@ #![doc(rust_logo)] #![feature(box_patterns)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod helpers; diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index 389d8c2413bfa..bbd3308809c33 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -3,7 +3,6 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod attributes; diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 386f2c98447b4..249e71ef70dcf 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -80,7 +80,6 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end #[macro_use] diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs index f86a9db61c600..f3f6522f57587 100644 --- a/compiler/rustc_baked_icu_data/src/lib.rs +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -23,6 +23,7 @@ // tidy-alphabetical-start #![allow(elided_lifetimes_in_paths)] #![allow(internal_features)] +#![allow(unreachable_pub)] // because this crate is mostly generated code #![doc(rust_logo)] #![feature(rustdoc_internals)] // #![warn(unreachable_pub)] // don't use because this crate is mostly generated code diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index d1f238331d56f..208d510db2e1f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -505,7 +505,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let var_id = self.infcx.tcx.closure_captures(def_id)[field.index()].get_root_variable(); - Some(self.infcx.tcx.hir().name(var_id).to_string()) + Some(self.infcx.tcx.hir_name(var_id).to_string()) } _ => { // Might need a revision when the fields in trait RFC is implemented @@ -1124,7 +1124,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { def_id, target_place, places ); let hir_id = self.infcx.tcx.local_def_id_to_hir_id(def_id); - let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; + let expr = &self.infcx.tcx.hir_expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); if let &hir::ExprKind::Closure(&hir::Closure { kind, fn_decl_span, .. }) = expr { for (captured_place, place) in diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 145137f923691..3951b467961a5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -698,7 +698,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if !matches!(k, hir::AssocItemKind::Fn { .. }) { continue; } - if self.infcx.tcx.hir().name(hi) != self.infcx.tcx.hir().name(my_hir) { + if self.infcx.tcx.hir_name(hi) != self.infcx.tcx.hir_name(my_hir) { continue; } f_in_trait_opt = Some(hi); diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs index 876b8f214b017..7192a889adcbc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs +++ b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs @@ -105,7 +105,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let Some(opaque_def_id) = opaque_def_id.as_local() && let hir::OpaqueTyOrigin::FnReturn { parent, .. } = - tcx.hir().expect_opaque_ty(opaque_def_id).origin + tcx.hir_expect_opaque_ty(opaque_def_id).origin { if let Some(sugg) = impl_trait_overcapture_suggestion( tcx, diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index a15f9744bf310..412aaf70c3f19 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -343,7 +343,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { } }; let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }) = - tcx.hir().expect_expr(self.mir_hir_id()).kind + tcx.hir_expect_expr(self.mir_hir_id()).kind else { bug!("Closure is not defined by a closure expr"); }; diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs index 191c0444c742e..693d22abbe6c8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -69,7 +69,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let upvar_hir_id = upvars[upvar_index].get_root_variable(); debug!("get_upvar_name_and_span_for_region: upvar_hir_id={upvar_hir_id:?}"); - let upvar_name = tcx.hir().name(upvar_hir_id); + let upvar_name = tcx.hir_name(upvar_hir_id); let upvar_span = tcx.hir().span(upvar_hir_id); debug!( "get_upvar_name_and_span_for_region: upvar_name={upvar_name:?} upvar_span={upvar_span:?}", diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 64a533e05ffd4..4d3774682ce83 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -13,7 +13,6 @@ #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 9d5022f2bef4c..d2eb7a52f78a0 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -156,6 +156,7 @@ pub(crate) fn type_check<'a, 'tcx>( infcx, last_span: body.span, body, + promoted, user_type_annotations: &body.user_type_annotations, region_bound_pairs, known_type_outlives_obligations, @@ -170,11 +171,7 @@ pub(crate) fn type_check<'a, 'tcx>( }; typeck.check_user_type_annotations(); - - let mut verifier = TypeVerifier { typeck: &mut typeck, promoted, last_span: body.span }; - verifier.visit_body(body); - - typeck.typeck_mir(); + typeck.visit_body(body); typeck.equate_inputs_and_outputs(&normalized_inputs_and_output); typeck.check_signature_annotation(); @@ -212,318 +209,302 @@ enum FieldAccessError { OutOfRange { field_count: usize }, } -/// Verifies that MIR types are sane. -/// -/// FIXME: This should be merged with the actual `TypeChecker`. -struct TypeVerifier<'a, 'b, 'tcx> { - typeck: &'a mut TypeChecker<'b, 'tcx>, - promoted: &'b IndexSlice>, +/// The MIR type checker. Visits the MIR and enforces all the +/// constraints needed for it to be valid and well-typed. Along the +/// way, it accrues region constraints -- these can later be used by +/// NLL region checking. +struct TypeChecker<'a, 'tcx> { + infcx: &'a BorrowckInferCtxt<'tcx>, last_span: Span, + body: &'a Body<'tcx>, + /// The bodies of all promoteds. As promoteds have a completely separate CFG + /// recursing into them may corrupt your data structures if you're not careful. + promoted: &'a IndexSlice>, + /// User type annotations are shared between the main MIR and the MIR of + /// all of the promoted items. + user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, + region_bound_pairs: RegionBoundPairs<'tcx>, + known_type_outlives_obligations: Vec>, + implicit_region_bound: ty::Region<'tcx>, + reported_errors: FxIndexSet<(Ty<'tcx>, Span)>, + universal_regions: &'a UniversalRegions<'tcx>, + location_table: &'a PoloniusLocationTable, + polonius_facts: &'a mut Option, + borrow_set: &'a BorrowSet<'tcx>, + constraints: &'a mut MirTypeckRegionConstraints<'tcx>, + /// When using `-Zpolonius=next`, the liveness helper data used to create polonius constraints. + polonius_liveness: Option, } -impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { - fn visit_span(&mut self, span: Span) { - if !span.is_dummy() { - self.last_span = span; +/// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions +/// inference computation. +pub(crate) struct MirTypeckResults<'tcx> { + pub(crate) constraints: MirTypeckRegionConstraints<'tcx>, + pub(crate) universal_region_relations: Frozen>, + pub(crate) opaque_type_values: FxIndexMap, OpaqueHiddenType<'tcx>>, + pub(crate) polonius_context: Option, +} + +/// A collection of region constraints that must be satisfied for the +/// program to be considered well-typed. +pub(crate) struct MirTypeckRegionConstraints<'tcx> { + /// Maps from a `ty::Placeholder` to the corresponding + /// `PlaceholderIndex` bit that we will use for it. + /// + /// To keep everything in sync, do not insert this set + /// directly. Instead, use the `placeholder_region` helper. + pub(crate) placeholder_indices: PlaceholderIndices, + + /// Each time we add a placeholder to `placeholder_indices`, we + /// also create a corresponding "representative" region vid for + /// that wraps it. This vector tracks those. This way, when we + /// convert the same `ty::RePlaceholder(p)` twice, we can map to + /// the same underlying `RegionVid`. + pub(crate) placeholder_index_to_region: IndexVec>, + + /// In general, the type-checker is not responsible for enforcing + /// liveness constraints; this job falls to the region inferencer, + /// which performs a liveness analysis. However, in some limited + /// cases, the MIR type-checker creates temporary regions that do + /// not otherwise appear in the MIR -- in particular, the + /// late-bound regions that it instantiates at call-sites -- and + /// hence it must report on their liveness constraints. + pub(crate) liveness_constraints: LivenessValues, + + pub(crate) outlives_constraints: OutlivesConstraintSet<'tcx>, + + pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>, + + pub(crate) universe_causes: FxIndexMap>, + + pub(crate) type_tests: Vec>, +} + +impl<'tcx> MirTypeckRegionConstraints<'tcx> { + /// Creates a `Region` for a given `PlaceholderRegion`, or returns the + /// region that corresponds to a previously created one. + fn placeholder_region( + &mut self, + infcx: &InferCtxt<'tcx>, + placeholder: ty::PlaceholderRegion, + ) -> ty::Region<'tcx> { + let placeholder_index = self.placeholder_indices.insert(placeholder); + match self.placeholder_index_to_region.get(placeholder_index) { + Some(&v) => v, + None => { + let origin = NllRegionVariableOrigin::Placeholder(placeholder); + let region = infcx.next_nll_region_var_in_universe(origin, placeholder.universe); + self.placeholder_index_to_region.push(region); + region + } } } +} - fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { - self.super_place(place, context, location); - let tcx = self.tcx(); - let place_ty = place.ty(self.body(), tcx); - if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), - [place_ty.ty], - ); +/// The `Locations` type summarizes *where* region constraints are +/// required to hold. Normally, this is at a particular point which +/// created the obligation, but for constraints that the user gave, we +/// want the constraint to hold at all points. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub enum Locations { + /// Indicates that a type constraint should always be true. This + /// is particularly important in the new borrowck analysis for + /// things like the type of the return slot. Consider this + /// example: + /// + /// ```compile_fail,E0515 + /// fn foo<'a>(x: &'a u32) -> &'a u32 { + /// let y = 22; + /// return &y; // error + /// } + /// ``` + /// + /// Here, we wind up with the signature from the return type being + /// something like `&'1 u32` where `'1` is a universal region. But + /// the type of the return slot `_0` is something like `&'2 u32` + /// where `'2` is an existential region variable. The type checker + /// requires that `&'2 u32 = &'1 u32` -- but at what point? In the + /// older NLL analysis, we required this only at the entry point + /// to the function. By the nature of the constraints, this wound + /// up propagating to all points reachable from start (because + /// `'1` -- as a universal region -- is live everywhere). In the + /// newer analysis, though, this doesn't work: `_0` is considered + /// dead at the start (it has no usable value) and hence this type + /// equality is basically a no-op. Then, later on, when we do `_0 + /// = &'3 y`, that region `'3` never winds up related to the + /// universal region `'1` and hence no error occurs. Therefore, we + /// use Locations::All instead, which ensures that the `'1` and + /// `'2` are equal everything. We also use this for other + /// user-given type annotations; e.g., if the user wrote `let mut + /// x: &'static u32 = ...`, we would ensure that all values + /// assigned to `x` are of `'static` lifetime. + /// + /// The span points to the place the constraint arose. For example, + /// it points to the type in a user-given type annotation. If + /// there's no sensible span then it's DUMMY_SP. + All(Span), - // To have a `Copy` operand, the type `T` of the - // value must be `Copy`. Note that we prove that `T: Copy`, - // rather than using the `is_copy_modulo_regions` - // test. This is important because - // `is_copy_modulo_regions` ignores the resulting region - // obligations and assumes they pass. This can result in - // bounds from `Copy` impls being unsoundly ignored (e.g., - // #29149). Note that we decide to use `Copy` before knowing - // whether the bounds fully apply: in effect, the rule is - // that if a value of some type could implement `Copy`, then - // it must. - self.typeck.prove_trait_ref( - trait_ref, - location.to_locations(), - ConstraintCategory::CopyBound, - ); + /// An outlives constraint that only has to hold at a single location, + /// usually it represents a point where references flow from one spot to + /// another (e.g., `x = y`) + Single(Location), +} + +impl Locations { + pub fn from_location(&self) -> Option { + match self { + Locations::All(_) => None, + Locations::Single(from_location) => Some(*from_location), } } - fn visit_projection_elem( - &mut self, - place: PlaceRef<'tcx>, - elem: PlaceElem<'tcx>, - context: PlaceContext, - location: Location, - ) { - let tcx = self.tcx(); - let base_ty = place.ty(self.body(), tcx); - match elem { - // All these projections don't add any constraints, so there's nothing to - // do here. We check their invariants in the MIR validator after all. - ProjectionElem::Deref - | ProjectionElem::Index(_) - | ProjectionElem::ConstantIndex { .. } - | ProjectionElem::Subslice { .. } - | ProjectionElem::Downcast(..) => {} - ProjectionElem::Field(field, fty) => { - let fty = self.typeck.normalize(fty, location); - let ty = base_ty.field_ty(tcx, field); - let ty = self.typeck.normalize(ty, location); - debug!(?fty, ?ty); - - if let Err(terr) = self.typeck.relate_types( - ty, - context.ambient_variance(), - fty, - location.to_locations(), - ConstraintCategory::Boring, - ) { - span_mirbug!(self, place, "bad field access ({:?}: {:?}): {:?}", ty, fty, terr); - } - } - ProjectionElem::OpaqueCast(ty) => { - let ty = self.typeck.normalize(ty, location); - self.typeck - .relate_types( - ty, - context.ambient_variance(), - base_ty.ty, - location.to_locations(), - ConstraintCategory::TypeAnnotation(AnnotationSource::OpaqueCast), - ) - .unwrap(); - } - ProjectionElem::UnwrapUnsafeBinder(ty) => { - let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else { - unreachable!(); - }; - let found_ty = self.typeck.infcx.instantiate_binder_with_fresh_vars( - self.body().source_info(location).span, - BoundRegionConversionTime::HigherRankedType, - binder_ty.into(), - ); - self.typeck - .relate_types( - ty, - context.ambient_variance(), - found_ty, - location.to_locations(), - ConstraintCategory::Boring, - ) - .unwrap(); - } - ProjectionElem::Subtype(_) => { - bug!("ProjectionElem::Subtype shouldn't exist in borrowck") - } + /// Gets a span representing the location. + pub fn span(&self, body: &Body<'_>) -> Span { + match self { + Locations::All(span) => *span, + Locations::Single(l) => body.source_info(*l).span, } } +} - #[instrument(level = "debug", skip(self))] - fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) { - self.super_const_operand(constant, location); - let ty = constant.const_.ty(); +impl<'a, 'tcx> TypeChecker<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.infcx.tcx + } - self.typeck.infcx.tcx.for_each_free_region(&ty, |live_region| { - let live_region_vid = self.typeck.universal_regions.to_region_vid(live_region); - self.typeck.constraints.liveness_constraints.add_location(live_region_vid, location); - }); + fn body(&self) -> &Body<'tcx> { + self.body + } - let locations = location.to_locations(); - if let Some(annotation_index) = constant.user_ty { - if let Err(terr) = self.typeck.relate_type_and_user_type( - constant.const_.ty(), - ty::Invariant, - &UserTypeProjection { base: annotation_index, projs: vec![] }, - locations, - ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg), - ) { - let annotation = &self.typeck.user_type_annotations[annotation_index]; - span_mirbug!( - self, - constant, - "bad constant user type {:?} vs {:?}: {:?}", - annotation, - constant.const_.ty(), - terr, - ); - } + fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> RegionVid { + if let ty::RePlaceholder(placeholder) = r.kind() { + self.constraints.placeholder_region(self.infcx, placeholder).as_var() } else { - let tcx = self.tcx(); - let maybe_uneval = match constant.const_ { - Const::Ty(_, ct) => match ct.kind() { - ty::ConstKind::Unevaluated(uv) => { - Some(UnevaluatedConst { def: uv.def, args: uv.args, promoted: None }) - } - _ => None, - }, - Const::Unevaluated(uv, _) => Some(uv), - _ => None, - }; - - if let Some(uv) = maybe_uneval { - if let Some(promoted) = uv.promoted { - let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, - promoted: &Body<'tcx>, - ty, - san_ty| { - if let Err(terr) = verifier.typeck.eq_types( - ty, - san_ty, - locations, - ConstraintCategory::Boring, - ) { - span_mirbug!( - verifier, - promoted, - "bad promoted type ({:?}: {:?}): {:?}", - ty, - san_ty, - terr - ); - }; - }; - - let promoted_body = &self.promoted[promoted]; - self.verify_promoted(promoted_body, location); - - let promoted_ty = promoted_body.return_ty(); - check_err(self, promoted_body, ty, promoted_ty); - } else { - self.typeck.ascribe_user_type( - constant.const_.ty(), - ty::UserType::new(ty::UserTypeKind::TypeOf( - uv.def, - UserArgs { args: uv.args, user_self_ty: None }, - )), - locations.span(self.typeck.body), - ); - } - } else if let Some(static_def_id) = constant.check_static_ptr(tcx) { - let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity(); - let normalized_ty = self.typeck.normalize(unnormalized_ty, locations); - let literal_ty = constant.const_.ty().builtin_deref(true).unwrap(); - - if let Err(terr) = self.typeck.eq_types( - literal_ty, - normalized_ty, - locations, - ConstraintCategory::Boring, - ) { - span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr); - } - } + self.universal_regions.to_region_vid(r) + } + } - if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() { - let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args); - self.typeck.normalize_and_prove_instantiated_predicates( - def_id, - instantiated_predicates, - locations, - ); + fn unsized_feature_enabled(&self) -> bool { + let features = self.tcx().features(); + features.unsized_locals() || features.unsized_fn_params() + } - assert!(!matches!( - tcx.impl_of_method(def_id).map(|imp| tcx.def_kind(imp)), - Some(DefKind::Impl { of_trait: true }) - )); - self.typeck.prove_predicates( - args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())), - locations, - ConstraintCategory::Boring, - ); + /// Equate the inferred type and the annotated type for user type annotations + #[instrument(skip(self), level = "debug")] + fn check_user_type_annotations(&mut self) { + debug!(?self.user_type_annotations); + let tcx = self.tcx(); + for user_annotation in self.user_type_annotations { + let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation; + let annotation = self.instantiate_canonical(span, user_ty); + if let ty::UserTypeKind::TypeOf(def, args) = annotation.kind + && let DefKind::InlineConst = tcx.def_kind(def) + { + assert!(annotation.bounds.is_empty()); + self.check_inline_const(inferred_ty, def.expect_local(), args, span); + } else { + self.ascribe_user_type(inferred_ty, annotation, span); } } } - fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { - self.super_local_decl(local, local_decl); + #[instrument(skip(self, data), level = "debug")] + fn push_region_constraints( + &mut self, + locations: Locations, + category: ConstraintCategory<'tcx>, + data: &QueryRegionConstraints<'tcx>, + ) { + debug!("constraints generated: {:#?}", data); - for user_ty in - local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections) - { - let span = self.typeck.user_type_annotations[user_ty.base].span; + constraint_conversion::ConstraintConversion::new( + self.infcx, + self.universal_regions, + &self.region_bound_pairs, + self.implicit_region_bound, + self.infcx.param_env, + &self.known_type_outlives_obligations, + locations, + locations.span(self.body), + category, + self.constraints, + ) + .convert_all(data); + } - let ty = if local_decl.is_nonref_binding() { - local_decl.ty - } else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() { - // If we have a binding of the form `let ref x: T = ..` - // then remove the outermost reference so we can check the - // type annotation for the remaining type. - rty - } else { - bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty); - }; + /// Try to relate `sub <: sup` + fn sub_types( + &mut self, + sub: Ty<'tcx>, + sup: Ty<'tcx>, + locations: Locations, + category: ConstraintCategory<'tcx>, + ) -> Result<(), NoSolution> { + // Use this order of parameters because the sup type is usually the + // "expected" type in diagnostics. + self.relate_types(sup, ty::Contravariant, sub, locations, category) + } - if let Err(terr) = self.typeck.relate_type_and_user_type( - ty, - ty::Invariant, - user_ty, - Locations::All(span), - ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration), - ) { - span_mirbug!( - self, - local, - "bad user type on variable {:?}: {:?} != {:?} ({:?})", - local, - local_decl.ty, - local_decl.user_ty, - terr, - ); - } - } + #[instrument(skip(self, category), level = "debug")] + fn eq_types( + &mut self, + expected: Ty<'tcx>, + found: Ty<'tcx>, + locations: Locations, + category: ConstraintCategory<'tcx>, + ) -> Result<(), NoSolution> { + self.relate_types(expected, ty::Invariant, found, locations, category) } - #[instrument(level = "debug", skip(self))] - fn visit_body(&mut self, body: &Body<'tcx>) { - debug_assert!(std::ptr::eq(self.typeck.body, body)); - // We intentionally do not recurse into `body.required_consts` or - // `body.mentioned_items` here as the MIR at this phase should still - // refer to all items and we don't want to check them multiple times. + #[instrument(skip(self), level = "debug")] + fn relate_type_and_user_type( + &mut self, + a: Ty<'tcx>, + v: ty::Variance, + user_ty: &UserTypeProjection, + locations: Locations, + category: ConstraintCategory<'tcx>, + ) -> Result<(), NoSolution> { + let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty; + trace!(?annotated_type); + let mut curr_projected_ty = PlaceTy::from_ty(annotated_type); - for (local, local_decl) in body.local_decls.iter_enumerated() { - self.visit_local_decl(local, local_decl); - } + let tcx = self.infcx.tcx; - for (block, block_data) in body.basic_blocks.iter_enumerated() { - let mut location = Location { block, statement_index: 0 }; - for stmt in &block_data.statements { - if !stmt.source_info.span.is_dummy() { - self.last_span = stmt.source_info.span; - } - self.visit_statement(stmt, location); - location.statement_index += 1; + for proj in &user_ty.projs { + if !self.infcx.next_trait_solver() + && let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind() + { + // There is nothing that we can compare here if we go through an opaque type. + // We're always in its defining scope as we can otherwise not project through + // it, so we're constraining it anyways. + return Ok(()); } - - self.visit_terminator(block_data.terminator(), location); + let projected_ty = curr_projected_ty.projection_ty_core( + tcx, + proj, + |this, field, ()| { + let ty = this.field_ty(tcx, field); + self.structurally_resolve(ty, locations) + }, + |_, _| unreachable!(), + ); + curr_projected_ty = projected_ty; } - } -} + trace!(?curr_projected_ty); -impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { - fn body(&self) -> &Body<'tcx> { - self.typeck.body - } + let ty = curr_projected_ty.ty; + self.relate_types(ty, v.xform(ty::Contravariant), a, locations, category)?; - fn tcx(&self) -> TyCtxt<'tcx> { - self.typeck.infcx.tcx + Ok(()) } - fn verify_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Location) { + fn check_promoted(&mut self, promoted_body: &'a Body<'tcx>, location: Location) { // Determine the constraints from the promoted MIR by running the type // checker on the promoted MIR, then transfer the constraints back to // the main MIR, changing the locations to the provided location. - let parent_body = mem::replace(&mut self.typeck.body, promoted_body); + let parent_body = mem::replace(&mut self.body, promoted_body); // Use new sets of constraints and closure bounds so that we can // modify their locations. @@ -531,24 +512,23 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let mut constraints = Default::default(); let mut liveness_constraints = LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body))); - // Don't try to add borrow_region facts for the promoted MIR + // Don't try to add borrow_region facts for the promoted MIR as they refer + // to the wrong locations. let mut swap_constraints = |this: &mut Self| { - mem::swap(this.typeck.polonius_facts, polonius_facts); - mem::swap(&mut this.typeck.constraints.outlives_constraints, &mut constraints); - mem::swap(&mut this.typeck.constraints.liveness_constraints, &mut liveness_constraints); + mem::swap(this.polonius_facts, polonius_facts); + mem::swap(&mut this.constraints.outlives_constraints, &mut constraints); + mem::swap(&mut this.constraints.liveness_constraints, &mut liveness_constraints); }; swap_constraints(self); self.visit_body(promoted_body); - self.typeck.typeck_mir(); + self.body = parent_body; - self.typeck.body = parent_body; // Merge the outlives constraints back in, at the given location. swap_constraints(self); - let locations = location.to_locations(); for constraint in constraints.outlives().iter() { let mut constraint = *constraint; @@ -561,7 +541,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { // temporary from the user's point of view. constraint.category = ConstraintCategory::Boring; } - self.typeck.constraints.outlives_constraints.push(constraint) + self.constraints.outlives_constraints.push(constraint) } // If the region is live at least one location in the promoted MIR, // then add a liveness constraint to the main MIR for this region @@ -571,390 +551,131 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { // unordered. #[allow(rustc::potential_query_instability)] for region in liveness_constraints.live_regions_unordered() { - self.typeck.constraints.liveness_constraints.add_location(region, location); + self.constraints.liveness_constraints.add_location(region, location); } } -} -/// The MIR type checker. Visits the MIR and enforces all the -/// constraints needed for it to be valid and well-typed. Along the -/// way, it accrues region constraints -- these can later be used by -/// NLL region checking. -struct TypeChecker<'a, 'tcx> { - infcx: &'a BorrowckInferCtxt<'tcx>, - last_span: Span, - body: &'a Body<'tcx>, - /// User type annotations are shared between the main MIR and the MIR of - /// all of the promoted items. - user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, - region_bound_pairs: RegionBoundPairs<'tcx>, - known_type_outlives_obligations: Vec>, - implicit_region_bound: ty::Region<'tcx>, - reported_errors: FxIndexSet<(Ty<'tcx>, Span)>, - universal_regions: &'a UniversalRegions<'tcx>, - location_table: &'a PoloniusLocationTable, - polonius_facts: &'a mut Option, - borrow_set: &'a BorrowSet<'tcx>, - constraints: &'a mut MirTypeckRegionConstraints<'tcx>, - /// When using `-Zpolonius=next`, the liveness helper data used to create polonius constraints. - polonius_liveness: Option, + fn check_inline_const( + &mut self, + inferred_ty: Ty<'tcx>, + def_id: LocalDefId, + args: UserArgs<'tcx>, + span: Span, + ) { + assert!(args.user_self_ty.is_none()); + let tcx = self.tcx(); + let const_ty = tcx.type_of(def_id).instantiate(tcx, args.args); + if let Err(terr) = + self.eq_types(const_ty, inferred_ty, Locations::All(span), ConstraintCategory::Boring) + { + span_bug!( + span, + "bad inline const pattern: ({:?} = {:?}) {:?}", + const_ty, + inferred_ty, + terr + ); + } + let args = self.infcx.resolve_vars_if_possible(args.args); + let predicates = self.prove_closure_bounds(tcx, def_id, args, Locations::All(span)); + self.normalize_and_prove_instantiated_predicates( + def_id.to_def_id(), + predicates, + Locations::All(span), + ); + } } -/// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions -/// inference computation. -pub(crate) struct MirTypeckResults<'tcx> { - pub(crate) constraints: MirTypeckRegionConstraints<'tcx>, - pub(crate) universal_region_relations: Frozen>, - pub(crate) opaque_type_values: FxIndexMap, OpaqueHiddenType<'tcx>>, - pub(crate) polonius_context: Option, -} - -/// A collection of region constraints that must be satisfied for the -/// program to be considered well-typed. -pub(crate) struct MirTypeckRegionConstraints<'tcx> { - /// Maps from a `ty::Placeholder` to the corresponding - /// `PlaceholderIndex` bit that we will use for it. - /// - /// To keep everything in sync, do not insert this set - /// directly. Instead, use the `placeholder_region` helper. - pub(crate) placeholder_indices: PlaceholderIndices, - - /// Each time we add a placeholder to `placeholder_indices`, we - /// also create a corresponding "representative" region vid for - /// that wraps it. This vector tracks those. This way, when we - /// convert the same `ty::RePlaceholder(p)` twice, we can map to - /// the same underlying `RegionVid`. - pub(crate) placeholder_index_to_region: IndexVec>, - - /// In general, the type-checker is not responsible for enforcing - /// liveness constraints; this job falls to the region inferencer, - /// which performs a liveness analysis. However, in some limited - /// cases, the MIR type-checker creates temporary regions that do - /// not otherwise appear in the MIR -- in particular, the - /// late-bound regions that it instantiates at call-sites -- and - /// hence it must report on their liveness constraints. - pub(crate) liveness_constraints: LivenessValues, - - pub(crate) outlives_constraints: OutlivesConstraintSet<'tcx>, - - pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>, - - pub(crate) universe_causes: FxIndexMap>, - - pub(crate) type_tests: Vec>, -} - -impl<'tcx> MirTypeckRegionConstraints<'tcx> { - /// Creates a `Region` for a given `PlaceholderRegion`, or returns the - /// region that corresponds to a previously created one. - fn placeholder_region( - &mut self, - infcx: &InferCtxt<'tcx>, - placeholder: ty::PlaceholderRegion, - ) -> ty::Region<'tcx> { - let placeholder_index = self.placeholder_indices.insert(placeholder); - match self.placeholder_index_to_region.get(placeholder_index) { - Some(&v) => v, - None => { - let origin = NllRegionVariableOrigin::Placeholder(placeholder); - let region = infcx.next_nll_region_var_in_universe(origin, placeholder.universe); - self.placeholder_index_to_region.push(region); - region - } +impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { + fn visit_span(&mut self, span: Span) { + if !span.is_dummy() { + debug!(?span); + self.last_span = span; } } -} - -/// The `Locations` type summarizes *where* region constraints are -/// required to hold. Normally, this is at a particular point which -/// created the obligation, but for constraints that the user gave, we -/// want the constraint to hold at all points. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub enum Locations { - /// Indicates that a type constraint should always be true. This - /// is particularly important in the new borrowck analysis for - /// things like the type of the return slot. Consider this - /// example: - /// - /// ```compile_fail,E0515 - /// fn foo<'a>(x: &'a u32) -> &'a u32 { - /// let y = 22; - /// return &y; // error - /// } - /// ``` - /// - /// Here, we wind up with the signature from the return type being - /// something like `&'1 u32` where `'1` is a universal region. But - /// the type of the return slot `_0` is something like `&'2 u32` - /// where `'2` is an existential region variable. The type checker - /// requires that `&'2 u32 = &'1 u32` -- but at what point? In the - /// older NLL analysis, we required this only at the entry point - /// to the function. By the nature of the constraints, this wound - /// up propagating to all points reachable from start (because - /// `'1` -- as a universal region -- is live everywhere). In the - /// newer analysis, though, this doesn't work: `_0` is considered - /// dead at the start (it has no usable value) and hence this type - /// equality is basically a no-op. Then, later on, when we do `_0 - /// = &'3 y`, that region `'3` never winds up related to the - /// universal region `'1` and hence no error occurs. Therefore, we - /// use Locations::All instead, which ensures that the `'1` and - /// `'2` are equal everything. We also use this for other - /// user-given type annotations; e.g., if the user wrote `let mut - /// x: &'static u32 = ...`, we would ensure that all values - /// assigned to `x` are of `'static` lifetime. - /// - /// The span points to the place the constraint arose. For example, - /// it points to the type in a user-given type annotation. If - /// there's no sensible span then it's DUMMY_SP. - All(Span), - - /// An outlives constraint that only has to hold at a single location, - /// usually it represents a point where references flow from one spot to - /// another (e.g., `x = y`) - Single(Location), -} -impl Locations { - pub fn from_location(&self) -> Option { - match self { - Locations::All(_) => None, - Locations::Single(from_location) => Some(*from_location), - } - } + #[instrument(skip(self, body), level = "debug")] + fn visit_body(&mut self, body: &Body<'tcx>) { + debug_assert!(std::ptr::eq(self.body, body)); - /// Gets a span representing the location. - pub fn span(&self, body: &Body<'_>) -> Span { - match self { - Locations::All(span) => *span, - Locations::Single(l) => body.source_info(*l).span, + for (local, local_decl) in body.local_decls.iter_enumerated() { + self.visit_local_decl(local, local_decl); } - } -} -impl<'a, 'tcx> TypeChecker<'a, 'tcx> { - fn body(&self) -> &Body<'tcx> { - self.body - } + for (block, block_data) in body.basic_blocks.iter_enumerated() { + let mut location = Location { block, statement_index: 0 }; + for stmt in &block_data.statements { + self.visit_statement(stmt, location); + location.statement_index += 1; + } - fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> RegionVid { - if let ty::RePlaceholder(placeholder) = r.kind() { - self.constraints.placeholder_region(self.infcx, placeholder).as_var() - } else { - self.universal_regions.to_region_vid(r) + self.visit_terminator(block_data.terminator(), location); + self.check_iscleanup(block_data); } } - fn unsized_feature_enabled(&self) -> bool { - let features = self.tcx().features(); - features.unsized_locals() || features.unsized_fn_params() - } - - /// Equate the inferred type and the annotated type for user type annotations #[instrument(skip(self), level = "debug")] - fn check_user_type_annotations(&mut self) { - debug!(?self.user_type_annotations); + fn visit_statement(&mut self, stmt: &Statement<'tcx>, location: Location) { + self.super_statement(stmt, location); let tcx = self.tcx(); - for user_annotation in self.user_type_annotations { - let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation; - let annotation = self.instantiate_canonical(span, user_ty); - if let ty::UserTypeKind::TypeOf(def, args) = annotation.kind - && let DefKind::InlineConst = tcx.def_kind(def) - { - assert!(annotation.bounds.is_empty()); - self.check_inline_const(inferred_ty, def.expect_local(), args, span); - } else { - self.ascribe_user_type(inferred_ty, annotation, span); - } - } - } - - #[instrument(skip(self, data), level = "debug")] - fn push_region_constraints( - &mut self, - locations: Locations, - category: ConstraintCategory<'tcx>, - data: &QueryRegionConstraints<'tcx>, - ) { - debug!("constraints generated: {:#?}", data); + match &stmt.kind { + StatementKind::Assign(box (place, rv)) => { + // Assignments to temporaries are not "interesting"; + // they are not caused by the user, but rather artifacts + // of lowering. Assignments to other sorts of places *are* interesting + // though. + let category = match place.as_local() { + Some(RETURN_PLACE) => { + let defining_ty = &self.universal_regions.defining_ty; + if defining_ty.is_const() { + if tcx.is_static(defining_ty.def_id()) { + ConstraintCategory::UseAsStatic + } else { + ConstraintCategory::UseAsConst + } + } else { + ConstraintCategory::Return(ReturnConstraint::Normal) + } + } + Some(l) + if matches!( + self.body.local_decls[l].local_info(), + LocalInfo::AggregateTemp + ) => + { + ConstraintCategory::Usage + } + Some(l) if !self.body.local_decls[l].is_user_variable() => { + ConstraintCategory::Boring + } + _ => ConstraintCategory::Assignment, + }; + debug!( + "assignment category: {:?} {:?}", + category, + place.as_local().map(|l| &self.body.local_decls[l]) + ); - constraint_conversion::ConstraintConversion::new( - self.infcx, - self.universal_regions, - &self.region_bound_pairs, - self.implicit_region_bound, - self.infcx.param_env, - &self.known_type_outlives_obligations, - locations, - locations.span(self.body), - category, - self.constraints, - ) - .convert_all(data); - } - - /// Try to relate `sub <: sup` - fn sub_types( - &mut self, - sub: Ty<'tcx>, - sup: Ty<'tcx>, - locations: Locations, - category: ConstraintCategory<'tcx>, - ) -> Result<(), NoSolution> { - // Use this order of parameters because the sup type is usually the - // "expected" type in diagnostics. - self.relate_types(sup, ty::Contravariant, sub, locations, category) - } - - #[instrument(skip(self, category), level = "debug")] - fn eq_types( - &mut self, - expected: Ty<'tcx>, - found: Ty<'tcx>, - locations: Locations, - category: ConstraintCategory<'tcx>, - ) -> Result<(), NoSolution> { - self.relate_types(expected, ty::Invariant, found, locations, category) - } - - #[instrument(skip(self), level = "debug")] - fn relate_type_and_user_type( - &mut self, - a: Ty<'tcx>, - v: ty::Variance, - user_ty: &UserTypeProjection, - locations: Locations, - category: ConstraintCategory<'tcx>, - ) -> Result<(), NoSolution> { - let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty; - trace!(?annotated_type); - let mut curr_projected_ty = PlaceTy::from_ty(annotated_type); - - let tcx = self.infcx.tcx; - - for proj in &user_ty.projs { - if !self.infcx.next_trait_solver() - && let ty::Alias(ty::Opaque, ..) = curr_projected_ty.ty.kind() - { - // There is nothing that we can compare here if we go through an opaque type. - // We're always in its defining scope as we can otherwise not project through - // it, so we're constraining it anyways. - return Ok(()); - } - let projected_ty = curr_projected_ty.projection_ty_core( - tcx, - proj, - |this, field, ()| { - let ty = this.field_ty(tcx, field); - self.structurally_resolve(ty, locations) - }, - |_, _| unreachable!(), - ); - curr_projected_ty = projected_ty; - } - trace!(?curr_projected_ty); - - let ty = curr_projected_ty.ty; - self.relate_types(ty, v.xform(ty::Contravariant), a, locations, category)?; - - Ok(()) - } - - fn check_inline_const( - &mut self, - inferred_ty: Ty<'tcx>, - def_id: LocalDefId, - args: UserArgs<'tcx>, - span: Span, - ) { - assert!(args.user_self_ty.is_none()); - let tcx = self.tcx(); - let const_ty = tcx.type_of(def_id).instantiate(tcx, args.args); - if let Err(terr) = - self.eq_types(const_ty, inferred_ty, Locations::All(span), ConstraintCategory::Boring) - { - span_bug!( - span, - "bad inline const pattern: ({:?} = {:?}) {:?}", - const_ty, - inferred_ty, - terr - ); - } - let args = self.infcx.resolve_vars_if_possible(args.args); - let predicates = self.prove_closure_bounds(tcx, def_id, args, Locations::All(span)); - self.normalize_and_prove_instantiated_predicates( - def_id.to_def_id(), - predicates, - Locations::All(span), - ); - } - - fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - #[instrument(skip(self), level = "debug")] - fn check_stmt(&mut self, stmt: &Statement<'tcx>, location: Location) { - let tcx = self.tcx(); - debug!("stmt kind: {:?}", stmt.kind); - match &stmt.kind { - StatementKind::Assign(box (place, rv)) => { - // Assignments to temporaries are not "interesting"; - // they are not caused by the user, but rather artifacts - // of lowering. Assignments to other sorts of places *are* interesting - // though. - let category = match place.as_local() { - Some(RETURN_PLACE) => { - let defining_ty = &self.universal_regions.defining_ty; - if defining_ty.is_const() { - if tcx.is_static(defining_ty.def_id()) { - ConstraintCategory::UseAsStatic - } else { - ConstraintCategory::UseAsConst - } - } else { - ConstraintCategory::Return(ReturnConstraint::Normal) - } - } - Some(l) - if matches!( - self.body.local_decls[l].local_info(), - LocalInfo::AggregateTemp - ) => - { - ConstraintCategory::Usage - } - Some(l) if !self.body.local_decls[l].is_user_variable() => { - ConstraintCategory::Boring - } - _ => ConstraintCategory::Assignment, - }; - debug!( - "assignment category: {:?} {:?}", - category, - place.as_local().map(|l| &self.body.local_decls[l]) - ); - - let place_ty = place.ty(self.body, tcx).ty; - debug!(?place_ty); - let place_ty = self.normalize(place_ty, location); - debug!("place_ty normalized: {:?}", place_ty); - let rv_ty = rv.ty(self.body, tcx); - debug!(?rv_ty); - let rv_ty = self.normalize(rv_ty, location); - debug!("normalized rv_ty: {:?}", rv_ty); - if let Err(terr) = - self.sub_types(rv_ty, place_ty, location.to_locations(), category) - { - span_mirbug!( - self, - stmt, - "bad assignment ({:?} = {:?}): {:?}", - place_ty, - rv_ty, - terr - ); - } + let place_ty = place.ty(self.body, tcx).ty; + debug!(?place_ty); + let place_ty = self.normalize(place_ty, location); + debug!("place_ty normalized: {:?}", place_ty); + let rv_ty = rv.ty(self.body, tcx); + debug!(?rv_ty); + let rv_ty = self.normalize(rv_ty, location); + debug!("normalized rv_ty: {:?}", rv_ty); + if let Err(terr) = + self.sub_types(rv_ty, place_ty, location.to_locations(), category) + { + span_mirbug!( + self, + stmt, + "bad assignment ({:?} = {:?}): {:?}", + place_ty, + rv_ty, + terr + ); + } if let Some(annotation_index) = self.rvalue_user_ty(rv) { if let Err(terr) = self.relate_type_and_user_type( @@ -976,7 +697,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - self.check_rvalue(rv, location); if !self.unsized_feature_enabled() { let trait_ref = ty::TraitRef::new( tcx, @@ -1011,14 +731,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } } - StatementKind::Intrinsic(box kind) => match kind { - NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location), - NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!( - stmt.source_info.span, - "Unexpected NonDivergingIntrinsic::CopyNonOverlapping, should only appear after lowering_intrinsics", - ), - }, - StatementKind::FakeRead(..) + StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(..)) + | StatementKind::FakeRead(..) | StatementKind::StorageLive(..) | StatementKind::StorageDead(..) | StatementKind::Retag { .. } @@ -1027,14 +741,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | StatementKind::PlaceMention(..) | StatementKind::BackwardIncompatibleDropHint { .. } | StatementKind::Nop => {} - StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { + StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(..)) + | StatementKind::Deinit(..) + | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } } } - #[instrument(skip(self, term_location), level = "debug")] - fn check_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location) { + #[instrument(skip(self), level = "debug")] + fn visit_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location) { + self.super_terminator(term, term_location); let tcx = self.tcx(); debug!("terminator kind: {:?}", term.kind); match &term.kind { @@ -1052,8 +769,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } TerminatorKind::SwitchInt { discr, .. } => { - self.check_operand(discr, term_location); - let switch_ty = discr.ty(self.body, tcx); if !switch_ty.is_integral() && !switch_ty.is_char() && !switch_ty.is_bool() { span_mirbug!(self, term, "bad SwitchInt discr ty {:?}", switch_ty); @@ -1068,11 +783,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { _ => unreachable!(), }; - self.check_operand(func, term_location); - for arg in args { - self.check_operand(&arg.node, term_location); - } - let func_ty = func.ty(self.body, tcx); debug!("func_ty.kind: {:?}", func_ty.kind()); @@ -1159,8 +869,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_call_inputs(term, func, &sig, args, term_location, call_source); } TerminatorKind::Assert { cond, msg, .. } => { - self.check_operand(cond, term_location); - let cond_ty = cond.ty(self.body, tcx); if cond_ty != tcx.types.bool { span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty); @@ -1176,8 +884,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } TerminatorKind::Yield { value, resume_arg, .. } => { - self.check_operand(value, term_location); - match self.body.yield_ty() { None => span_mirbug!(self, term, "yield in non-coroutine"), Some(ty) => { @@ -1225,456 +931,142 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - fn check_call_dest( - &mut self, - term: &Terminator<'tcx>, - sig: &ty::FnSig<'tcx>, - destination: Place<'tcx>, - target: Option, - term_location: Location, - ) { - let tcx = self.tcx(); - match target { - Some(_) => { - let dest_ty = destination.ty(self.body, tcx).ty; - let dest_ty = self.normalize(dest_ty, term_location); - let category = match destination.as_local() { - Some(RETURN_PLACE) => { - if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) = - self.universal_regions.defining_ty - { - if tcx.is_static(def_id) { - ConstraintCategory::UseAsStatic - } else { - ConstraintCategory::UseAsConst - } - } else { - ConstraintCategory::Return(ReturnConstraint::Normal) - } - } - Some(l) if !self.body.local_decls[l].is_user_variable() => { - ConstraintCategory::Boring - } - // The return type of a call is interesting for diagnostics. - _ => ConstraintCategory::Assignment, - }; + fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { + self.super_local_decl(local, local_decl); - let locations = term_location.to_locations(); + for user_ty in + local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections) + { + let span = self.user_type_annotations[user_ty.base].span; - if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) { - span_mirbug!( - self, - term, - "call dest mismatch ({:?} <- {:?}): {:?}", - dest_ty, - sig.output(), - terr - ); - } + let ty = if local_decl.is_nonref_binding() { + local_decl.ty + } else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() { + // If we have a binding of the form `let ref x: T = ..` + // then remove the outermost reference so we can check the + // type annotation for the remaining type. + rty + } else { + bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty); + }; - // When `unsized_fn_params` and `unsized_locals` are both not enabled, - // this check is done at `check_local`. - if self.unsized_feature_enabled() { - let span = term.source_info.span; - self.ensure_place_sized(dest_ty, span); - } - } - None => { - // The signature in this call can reference region variables, - // so erase them before calling a query. - let output_ty = self.tcx().erase_regions(sig.output()); - if !output_ty.is_privately_uninhabited( - self.tcx(), - self.infcx.typing_env(self.infcx.param_env), - ) { - span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); - } + if let Err(terr) = self.relate_type_and_user_type( + ty, + ty::Invariant, + user_ty, + Locations::All(span), + ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration), + ) { + span_mirbug!( + self, + local, + "bad user type on variable {:?}: {:?} != {:?} ({:?})", + local, + local_decl.ty, + local_decl.user_ty, + terr, + ); } } - } - #[instrument(level = "debug", skip(self, term, func, term_location, call_source))] - fn check_call_inputs( - &mut self, - term: &Terminator<'tcx>, - func: &Operand<'tcx>, - sig: &ty::FnSig<'tcx>, - args: &[Spanned>], - term_location: Location, - call_source: CallSource, - ) { - if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { - span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); - } - - let func_ty = func.ty(self.body, self.infcx.tcx); - if let ty::FnDef(def_id, _) = *func_ty.kind() { - // Some of the SIMD intrinsics are special: they need a particular argument to be a - // constant. (Eventually this should use const-generics, but those are not up for the - // task yet: https://github.com/rust-lang/rust/issues/85229.) - if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) = - self.tcx().intrinsic(def_id).map(|i| i.name) - { - let idx = match name { - sym::simd_shuffle => 2, - _ => 1, - }; - if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) { - self.tcx().dcx().emit_err(SimdIntrinsicArgConst { - span: term.source_info.span, - arg: idx + 1, - intrinsic: name.to_string(), - }); + // When `unsized_fn_params` or `unsized_locals` is enabled, only function calls + // and nullary ops are checked in `check_call_dest`. + if !self.unsized_feature_enabled() { + match self.body.local_kind(local) { + LocalKind::ReturnPointer | LocalKind::Arg => { + // return values of normal functions are required to be + // sized by typeck, but return values of ADT constructors are + // not because we don't include a `Self: Sized` bounds on them. + // + // Unbound parts of arguments were never required to be Sized + // - maybe we should make that a warning. + return; + } + LocalKind::Temp => { + let span = local_decl.source_info.span; + let ty = local_decl.ty; + self.ensure_place_sized(ty, span); } } } - debug!(?func_ty); + } - for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { - let op_arg_ty = op_arg.node.ty(self.body, self.tcx()); + #[instrument(skip(self), level = "debug")] + fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { + self.super_rvalue(rvalue, location); + let tcx = self.tcx(); + let span = self.body.source_info(location).span; + match rvalue { + Rvalue::Aggregate(ak, ops) => self.check_aggregate_rvalue(rvalue, ak, ops, location), - let op_arg_ty = self.normalize(op_arg_ty, term_location); - let category = if call_source.from_hir_call() { - ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_regions(func_ty))) - } else { - ConstraintCategory::Boring - }; - if let Err(terr) = - self.sub_types(op_arg_ty, *fn_arg, term_location.to_locations(), category) - { - span_mirbug!( - self, - term, - "bad arg #{:?} ({:?} <- {:?}): {:?}", - n, - fn_arg, - op_arg_ty, - terr + Rvalue::Repeat(operand, len) => { + let array_ty = rvalue.ty(self.body.local_decls(), tcx); + self.prove_predicate( + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(array_ty.into())), + Locations::Single(location), + ConstraintCategory::Boring, ); - } - } - } - - fn check_iscleanup(&mut self, block_data: &BasicBlockData<'tcx>) { - let is_cleanup = block_data.is_cleanup; - self.last_span = block_data.terminator().source_info.span; - match block_data.terminator().kind { - TerminatorKind::Goto { target } => { - self.assert_iscleanup(block_data, target, is_cleanup) - } - TerminatorKind::SwitchInt { ref targets, .. } => { - for target in targets.all_targets() { - self.assert_iscleanup(block_data, *target, is_cleanup); - } - } - TerminatorKind::UnwindResume => { - if !is_cleanup { - span_mirbug!(self, block_data, "resume on non-cleanup block!") - } - } - TerminatorKind::UnwindTerminate(_) => { - if !is_cleanup { - span_mirbug!(self, block_data, "terminate on non-cleanup block!") - } - } - TerminatorKind::Return => { - if is_cleanup { - span_mirbug!(self, block_data, "return on cleanup block") - } - } - TerminatorKind::TailCall { .. } => { - if is_cleanup { - span_mirbug!(self, block_data, "tailcall on cleanup block") - } - } - TerminatorKind::CoroutineDrop { .. } => { - if is_cleanup { - span_mirbug!(self, block_data, "coroutine_drop in cleanup block") - } - } - TerminatorKind::Yield { resume, drop, .. } => { - if is_cleanup { - span_mirbug!(self, block_data, "yield in cleanup block") - } - self.assert_iscleanup(block_data, resume, is_cleanup); - if let Some(drop) = drop { - self.assert_iscleanup(block_data, drop, is_cleanup); - } - } - TerminatorKind::Unreachable => {} - TerminatorKind::Drop { target, unwind, .. } - | TerminatorKind::Assert { target, unwind, .. } => { - self.assert_iscleanup(block_data, target, is_cleanup); - self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); - } - TerminatorKind::Call { ref target, unwind, .. } => { - if let &Some(target) = target { - self.assert_iscleanup(block_data, target, is_cleanup); - } - self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); - } - TerminatorKind::FalseEdge { real_target, imaginary_target } => { - self.assert_iscleanup(block_data, real_target, is_cleanup); - self.assert_iscleanup(block_data, imaginary_target, is_cleanup); - } - TerminatorKind::FalseUnwind { real_target, unwind } => { - self.assert_iscleanup(block_data, real_target, is_cleanup); - self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); - } - TerminatorKind::InlineAsm { ref targets, unwind, .. } => { - for &target in targets { - self.assert_iscleanup(block_data, target, is_cleanup); - } - self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); - } - } - } - fn assert_iscleanup(&mut self, ctxt: &dyn fmt::Debug, bb: BasicBlock, iscleanuppad: bool) { - if self.body[bb].is_cleanup != iscleanuppad { - span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad); - } - } + // If the length cannot be evaluated we must assume that the length can be larger + // than 1. + // If the length is larger than 1, the repeat expression will need to copy the + // element, so we require the `Copy` trait. + if len.try_to_target_usize(tcx).is_none_or(|len| len > 1) { + match operand { + Operand::Copy(..) | Operand::Constant(..) => { + // These are always okay: direct use of a const, or a value that can + // evidently be copied. + } + Operand::Move(place) => { + // Make sure that repeated elements implement `Copy`. + let ty = place.ty(self.body, tcx).ty; + let trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::Copy, Some(span)), + [ty], + ); - fn assert_iscleanup_unwind( - &mut self, - ctxt: &dyn fmt::Debug, - unwind: UnwindAction, - is_cleanup: bool, - ) { - match unwind { - UnwindAction::Cleanup(unwind) => { - if is_cleanup { - span_mirbug!(self, ctxt, "unwind on cleanup block") - } - self.assert_iscleanup(ctxt, unwind, true); - } - UnwindAction::Continue => { - if is_cleanup { - span_mirbug!(self, ctxt, "unwind on cleanup block") + self.prove_trait_ref( + trait_ref, + Locations::Single(location), + ConstraintCategory::CopyBound, + ); + } + } } } - UnwindAction::Unreachable | UnwindAction::Terminate(_) => (), - } - } - fn check_local(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { - match self.body.local_kind(local) { - LocalKind::ReturnPointer | LocalKind::Arg => { - // return values of normal functions are required to be - // sized by typeck, but return values of ADT constructors are - // not because we don't include a `Self: Sized` bounds on them. - // - // Unbound parts of arguments were never required to be Sized - // - maybe we should make that a warning. - return; - } - LocalKind::Temp => {} - } + &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { + let trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::Sized, Some(span)), + [ty], + ); - // When `unsized_fn_params` or `unsized_locals` is enabled, only function calls - // and nullary ops are checked in `check_call_dest`. - if !self.unsized_feature_enabled() { - let span = local_decl.source_info.span; - let ty = local_decl.ty; - self.ensure_place_sized(ty, span); - } - } + self.prove_trait_ref( + trait_ref, + location.to_locations(), + ConstraintCategory::SizedBound, + ); + } + &Rvalue::NullaryOp(NullOp::ContractChecks, _) => {} + &Rvalue::NullaryOp(NullOp::UbChecks, _) => {} - fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) { - let tcx = self.tcx(); + Rvalue::ShallowInitBox(_operand, ty) => { + let trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::Sized, Some(span)), + [*ty], + ); - // Erase the regions from `ty` to get a global type. The - // `Sized` bound in no way depends on precise regions, so this - // shouldn't affect `is_sized`. - let erased_ty = tcx.erase_regions(ty); - // FIXME(#132279): Using `Ty::is_sized` causes us to incorrectly handle opaques here. - if !erased_ty.is_sized(tcx, self.infcx.typing_env(self.infcx.param_env)) { - // in current MIR construction, all non-control-flow rvalue - // expressions evaluate through `as_temp` or `into` a return - // slot or local, so to find all unsized rvalues it is enough - // to check all temps, return slots and locals. - if self.reported_errors.replace((ty, span)).is_none() { - // While this is located in `nll::typeck` this error is not - // an NLL error, it's a required check to prevent creation - // of unsized rvalues in a call expression. - self.tcx().dcx().emit_err(MoveUnsized { ty, span }); - } - } - } - - fn aggregate_field_ty( - &mut self, - ak: &AggregateKind<'tcx>, - field_index: FieldIdx, - location: Location, - ) -> Result, FieldAccessError> { - let tcx = self.tcx(); - - match *ak { - AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => { - let def = tcx.adt_def(adt_did); - let variant = &def.variant(variant_index); - let adj_field_index = active_field_index.unwrap_or(field_index); - if let Some(field) = variant.fields.get(adj_field_index) { - Ok(self.normalize(field.ty(tcx, args), location)) - } else { - Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) - } - } - AggregateKind::Closure(_, args) => { - match args.as_closure().upvar_tys().get(field_index.as_usize()) { - Some(ty) => Ok(*ty), - None => Err(FieldAccessError::OutOfRange { - field_count: args.as_closure().upvar_tys().len(), - }), - } - } - AggregateKind::Coroutine(_, args) => { - // It doesn't make sense to look at a field beyond the prefix; - // these require a variant index, and are not initialized in - // aggregate rvalues. - match args.as_coroutine().prefix_tys().get(field_index.as_usize()) { - Some(ty) => Ok(*ty), - None => Err(FieldAccessError::OutOfRange { - field_count: args.as_coroutine().prefix_tys().len(), - }), - } - } - AggregateKind::CoroutineClosure(_, args) => { - match args.as_coroutine_closure().upvar_tys().get(field_index.as_usize()) { - Some(ty) => Ok(*ty), - None => Err(FieldAccessError::OutOfRange { - field_count: args.as_coroutine_closure().upvar_tys().len(), - }), - } - } - AggregateKind::Array(ty) => Ok(ty), - AggregateKind::Tuple | AggregateKind::RawPtr(..) => { - unreachable!("This should have been covered in check_rvalues"); - } - } - } - - fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) { - debug!(?op, ?location, "check_operand"); - - if let Operand::Constant(constant) = op { - let maybe_uneval = match constant.const_ { - Const::Val(..) | Const::Ty(_, _) => None, - Const::Unevaluated(uv, _) => Some(uv), - }; - - if let Some(uv) = maybe_uneval { - if uv.promoted.is_none() { - let tcx = self.tcx(); - let def_id = uv.def; - if tcx.def_kind(def_id) == DefKind::InlineConst { - let def_id = def_id.expect_local(); - let predicates = self.prove_closure_bounds( - tcx, - def_id, - uv.args, - location.to_locations(), - ); - self.normalize_and_prove_instantiated_predicates( - def_id.to_def_id(), - predicates, - location.to_locations(), - ); - } - } - } - } - } - - #[instrument(skip(self), level = "debug")] - fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { - let tcx = self.tcx(); - let span = self.body.source_info(location).span; - - match rvalue { - Rvalue::Aggregate(ak, ops) => { - for op in ops { - self.check_operand(op, location); - } - self.check_aggregate_rvalue(rvalue, ak, ops, location) - } - - Rvalue::Repeat(operand, len) => { - self.check_operand(operand, location); - - let array_ty = rvalue.ty(self.body.local_decls(), tcx); - self.prove_predicate( - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(array_ty.into())), - Locations::Single(location), - ConstraintCategory::Boring, - ); - - // If the length cannot be evaluated we must assume that the length can be larger - // than 1. - // If the length is larger than 1, the repeat expression will need to copy the - // element, so we require the `Copy` trait. - if len.try_to_target_usize(tcx).is_none_or(|len| len > 1) { - match operand { - Operand::Copy(..) | Operand::Constant(..) => { - // These are always okay: direct use of a const, or a value that can - // evidently be copied. - } - Operand::Move(place) => { - // Make sure that repeated elements implement `Copy`. - let ty = place.ty(self.body, tcx).ty; - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Copy, Some(span)), - [ty], - ); - - self.prove_trait_ref( - trait_ref, - Locations::Single(location), - ConstraintCategory::CopyBound, - ); - } - } - } - } - - &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Sized, Some(span)), - [ty], - ); - - self.prove_trait_ref( - trait_ref, - location.to_locations(), - ConstraintCategory::SizedBound, - ); - } - &Rvalue::NullaryOp(NullOp::ContractChecks, _) => {} - &Rvalue::NullaryOp(NullOp::UbChecks, _) => {} - - Rvalue::ShallowInitBox(operand, ty) => { - self.check_operand(operand, location); - - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Sized, Some(span)), - [*ty], - ); - - self.prove_trait_ref( - trait_ref, - location.to_locations(), - ConstraintCategory::SizedBound, - ); + self.prove_trait_ref( + trait_ref, + location.to_locations(), + ConstraintCategory::SizedBound, + ); } Rvalue::Cast(cast_kind, op, ty) => { - self.check_operand(op, location); - match *cast_kind { CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, coercion_source) => { let is_implicit_coercion = coercion_source == CoercionSource::Implicit; @@ -2148,139 +1540,662 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ty::Dyn, ); - debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); + debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); + + self.sub_types( + src_obj, + dst_obj, + location.to_locations(), + ConstraintCategory::Cast { + is_implicit_coercion: false, + unsize_to: None, + }, + ) + .unwrap(); + } + } + _ => { + span_mirbug!( + self, + rvalue, + "Invalid PtrToPtr cast {:?} -> {:?}", + ty_from, + ty + ) + } + } + } + CastKind::Transmute => { + span_mirbug!( + self, + rvalue, + "Unexpected CastKind::Transmute, which is not permitted in Analysis MIR", + ); + } + } + } + + Rvalue::Ref(region, _borrow_kind, borrowed_place) => { + self.add_reborrow_constraint(location, *region, borrowed_place); + } + + Rvalue::BinaryOp( + BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge, + box (left, right), + ) => { + let ty_left = left.ty(self.body, tcx); + match ty_left.kind() { + // Types with regions are comparable if they have a common super-type. + ty::RawPtr(_, _) | ty::FnPtr(..) => { + let ty_right = right.ty(self.body, tcx); + let common_ty = + self.infcx.next_ty_var(self.body.source_info(location).span); + self.sub_types( + ty_left, + common_ty, + location.to_locations(), + ConstraintCategory::CallArgument(None), + ) + .unwrap_or_else(|err| { + bug!("Could not equate type variable with {:?}: {:?}", ty_left, err) + }); + if let Err(terr) = self.sub_types( + ty_right, + common_ty, + location.to_locations(), + ConstraintCategory::CallArgument(None), + ) { + span_mirbug!( + self, + rvalue, + "unexpected comparison types {:?} and {:?} yields {:?}", + ty_left, + ty_right, + terr + ) + } + } + // For types with no regions we can just check that the + // both operands have the same type. + ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_) + if ty_left == right.ty(self.body, tcx) => {} + // Other types are compared by trait methods, not by + // `Rvalue::BinaryOp`. + _ => span_mirbug!( + self, + rvalue, + "unexpected comparison types {:?} and {:?}", + ty_left, + right.ty(self.body, tcx) + ), + } + } + + Rvalue::WrapUnsafeBinder(op, ty) => { + let operand_ty = op.ty(self.body, self.tcx()); + let ty::UnsafeBinder(binder_ty) = *ty.kind() else { + unreachable!(); + }; + let expected_ty = self.infcx.instantiate_binder_with_fresh_vars( + self.body().source_info(location).span, + BoundRegionConversionTime::HigherRankedType, + binder_ty.into(), + ); + self.sub_types( + operand_ty, + expected_ty, + location.to_locations(), + ConstraintCategory::Boring, + ) + .unwrap(); + } + + Rvalue::Use(_) + | Rvalue::UnaryOp(_, _) + | Rvalue::CopyForDeref(_) + | Rvalue::BinaryOp(..) + | Rvalue::RawPtr(..) + | Rvalue::ThreadLocalRef(..) + | Rvalue::Len(..) + | Rvalue::Discriminant(..) + | Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {} + } + } + + #[instrument(level = "debug", skip(self))] + fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { + self.super_operand(op, location); + if let Operand::Constant(constant) = op { + let maybe_uneval = match constant.const_ { + Const::Val(..) | Const::Ty(_, _) => None, + Const::Unevaluated(uv, _) => Some(uv), + }; + + if let Some(uv) = maybe_uneval { + if uv.promoted.is_none() { + let tcx = self.tcx(); + let def_id = uv.def; + if tcx.def_kind(def_id) == DefKind::InlineConst { + let def_id = def_id.expect_local(); + let predicates = self.prove_closure_bounds( + tcx, + def_id, + uv.args, + location.to_locations(), + ); + self.normalize_and_prove_instantiated_predicates( + def_id.to_def_id(), + predicates, + location.to_locations(), + ); + } + } + } + } + } + + #[instrument(level = "debug", skip(self))] + fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) { + self.super_const_operand(constant, location); + let ty = constant.const_.ty(); + + self.infcx.tcx.for_each_free_region(&ty, |live_region| { + let live_region_vid = self.universal_regions.to_region_vid(live_region); + self.constraints.liveness_constraints.add_location(live_region_vid, location); + }); + + let locations = location.to_locations(); + if let Some(annotation_index) = constant.user_ty { + if let Err(terr) = self.relate_type_and_user_type( + constant.const_.ty(), + ty::Invariant, + &UserTypeProjection { base: annotation_index, projs: vec![] }, + locations, + ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg), + ) { + let annotation = &self.user_type_annotations[annotation_index]; + span_mirbug!( + self, + constant, + "bad constant user type {:?} vs {:?}: {:?}", + annotation, + constant.const_.ty(), + terr, + ); + } + } else { + let tcx = self.tcx(); + let maybe_uneval = match constant.const_ { + Const::Ty(_, ct) => match ct.kind() { + ty::ConstKind::Unevaluated(uv) => { + Some(UnevaluatedConst { def: uv.def, args: uv.args, promoted: None }) + } + _ => None, + }, + Const::Unevaluated(uv, _) => Some(uv), + _ => None, + }; + + if let Some(uv) = maybe_uneval { + if let Some(promoted) = uv.promoted { + let promoted_body = &self.promoted[promoted]; + self.check_promoted(promoted_body, location); + let promoted_ty = promoted_body.return_ty(); + if let Err(terr) = + self.eq_types(ty, promoted_ty, locations, ConstraintCategory::Boring) + { + span_mirbug!( + self, + promoted, + "bad promoted type ({:?}: {:?}): {:?}", + ty, + promoted_ty, + terr + ); + }; + } else { + self.ascribe_user_type( + constant.const_.ty(), + ty::UserType::new(ty::UserTypeKind::TypeOf( + uv.def, + UserArgs { args: uv.args, user_self_ty: None }, + )), + locations.span(self.body), + ); + } + } else if let Some(static_def_id) = constant.check_static_ptr(tcx) { + let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity(); + let normalized_ty = self.normalize(unnormalized_ty, locations); + let literal_ty = constant.const_.ty().builtin_deref(true).unwrap(); + + if let Err(terr) = + self.eq_types(literal_ty, normalized_ty, locations, ConstraintCategory::Boring) + { + span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr); + } + } + + if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() { + let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args); + self.normalize_and_prove_instantiated_predicates( + def_id, + instantiated_predicates, + locations, + ); + + assert!(!matches!( + tcx.impl_of_method(def_id).map(|imp| tcx.def_kind(imp)), + Some(DefKind::Impl { of_trait: true }) + )); + self.prove_predicates( + args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())), + locations, + ConstraintCategory::Boring, + ); + } + } + } + + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { + self.super_place(place, context, location); + let tcx = self.tcx(); + let place_ty = place.ty(self.body, tcx); + if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { + let trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), + [place_ty.ty], + ); + + // To have a `Copy` operand, the type `T` of the + // value must be `Copy`. Note that we prove that `T: Copy`, + // rather than using the `is_copy_modulo_regions` + // test. This is important because + // `is_copy_modulo_regions` ignores the resulting region + // obligations and assumes they pass. This can result in + // bounds from `Copy` impls being unsoundly ignored (e.g., + // #29149). Note that we decide to use `Copy` before knowing + // whether the bounds fully apply: in effect, the rule is + // that if a value of some type could implement `Copy`, then + // it must. + self.prove_trait_ref(trait_ref, location.to_locations(), ConstraintCategory::CopyBound); + } + } + + fn visit_projection_elem( + &mut self, + place: PlaceRef<'tcx>, + elem: PlaceElem<'tcx>, + context: PlaceContext, + location: Location, + ) { + let tcx = self.tcx(); + let base_ty = place.ty(self.body(), tcx); + match elem { + // All these projections don't add any constraints, so there's nothing to + // do here. We check their invariants in the MIR validator after all. + ProjectionElem::Deref + | ProjectionElem::Index(_) + | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subslice { .. } + | ProjectionElem::Downcast(..) => {} + ProjectionElem::Field(field, fty) => { + let fty = self.normalize(fty, location); + let ty = base_ty.field_ty(tcx, field); + let ty = self.normalize(ty, location); + debug!(?fty, ?ty); + + if let Err(terr) = self.relate_types( + ty, + context.ambient_variance(), + fty, + location.to_locations(), + ConstraintCategory::Boring, + ) { + span_mirbug!(self, place, "bad field access ({:?}: {:?}): {:?}", ty, fty, terr); + } + } + ProjectionElem::OpaqueCast(ty) => { + let ty = self.normalize(ty, location); + self.relate_types( + ty, + context.ambient_variance(), + base_ty.ty, + location.to_locations(), + ConstraintCategory::TypeAnnotation(AnnotationSource::OpaqueCast), + ) + .unwrap(); + } + ProjectionElem::UnwrapUnsafeBinder(ty) => { + let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else { + unreachable!(); + }; + let found_ty = self.infcx.instantiate_binder_with_fresh_vars( + self.body.source_info(location).span, + BoundRegionConversionTime::HigherRankedType, + binder_ty.into(), + ); + self.relate_types( + ty, + context.ambient_variance(), + found_ty, + location.to_locations(), + ConstraintCategory::Boring, + ) + .unwrap(); + } + ProjectionElem::Subtype(_) => { + bug!("ProjectionElem::Subtype shouldn't exist in borrowck") + } + } + } +} + +impl<'a, 'tcx> TypeChecker<'a, 'tcx> { + fn check_call_dest( + &mut self, + term: &Terminator<'tcx>, + sig: &ty::FnSig<'tcx>, + destination: Place<'tcx>, + target: Option, + term_location: Location, + ) { + let tcx = self.tcx(); + match target { + Some(_) => { + let dest_ty = destination.ty(self.body, tcx).ty; + let dest_ty = self.normalize(dest_ty, term_location); + let category = match destination.as_local() { + Some(RETURN_PLACE) => { + if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) = + self.universal_regions.defining_ty + { + if tcx.is_static(def_id) { + ConstraintCategory::UseAsStatic + } else { + ConstraintCategory::UseAsConst + } + } else { + ConstraintCategory::Return(ReturnConstraint::Normal) + } + } + Some(l) if !self.body.local_decls[l].is_user_variable() => { + ConstraintCategory::Boring + } + // The return type of a call is interesting for diagnostics. + _ => ConstraintCategory::Assignment, + }; + + let locations = term_location.to_locations(); + + if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) { + span_mirbug!( + self, + term, + "call dest mismatch ({:?} <- {:?}): {:?}", + dest_ty, + sig.output(), + terr + ); + } + + // When `unsized_fn_params` and `unsized_locals` are both not enabled, + // this check is done at `check_local`. + if self.unsized_feature_enabled() { + let span = term.source_info.span; + self.ensure_place_sized(dest_ty, span); + } + } + None => { + // The signature in this call can reference region variables, + // so erase them before calling a query. + let output_ty = self.tcx().erase_regions(sig.output()); + if !output_ty.is_privately_uninhabited( + self.tcx(), + self.infcx.typing_env(self.infcx.param_env), + ) { + span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); + } + } + } + } + + #[instrument(level = "debug", skip(self, term, func, term_location, call_source))] + fn check_call_inputs( + &mut self, + term: &Terminator<'tcx>, + func: &Operand<'tcx>, + sig: &ty::FnSig<'tcx>, + args: &[Spanned>], + term_location: Location, + call_source: CallSource, + ) { + if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { + span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); + } + + let func_ty = func.ty(self.body, self.infcx.tcx); + if let ty::FnDef(def_id, _) = *func_ty.kind() { + // Some of the SIMD intrinsics are special: they need a particular argument to be a + // constant. (Eventually this should use const-generics, but those are not up for the + // task yet: https://github.com/rust-lang/rust/issues/85229.) + if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) = + self.tcx().intrinsic(def_id).map(|i| i.name) + { + let idx = match name { + sym::simd_shuffle => 2, + _ => 1, + }; + if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) { + self.tcx().dcx().emit_err(SimdIntrinsicArgConst { + span: term.source_info.span, + arg: idx + 1, + intrinsic: name.to_string(), + }); + } + } + } + debug!(?func_ty); + + for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { + let op_arg_ty = op_arg.node.ty(self.body, self.tcx()); + + let op_arg_ty = self.normalize(op_arg_ty, term_location); + let category = if call_source.from_hir_call() { + ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_regions(func_ty))) + } else { + ConstraintCategory::Boring + }; + if let Err(terr) = + self.sub_types(op_arg_ty, *fn_arg, term_location.to_locations(), category) + { + span_mirbug!( + self, + term, + "bad arg #{:?} ({:?} <- {:?}): {:?}", + n, + fn_arg, + op_arg_ty, + terr + ); + } + } + } + + fn check_iscleanup(&mut self, block_data: &BasicBlockData<'tcx>) { + let is_cleanup = block_data.is_cleanup; + match block_data.terminator().kind { + TerminatorKind::Goto { target } => { + self.assert_iscleanup(block_data, target, is_cleanup) + } + TerminatorKind::SwitchInt { ref targets, .. } => { + for target in targets.all_targets() { + self.assert_iscleanup(block_data, *target, is_cleanup); + } + } + TerminatorKind::UnwindResume => { + if !is_cleanup { + span_mirbug!(self, block_data, "resume on non-cleanup block!") + } + } + TerminatorKind::UnwindTerminate(_) => { + if !is_cleanup { + span_mirbug!(self, block_data, "terminate on non-cleanup block!") + } + } + TerminatorKind::Return => { + if is_cleanup { + span_mirbug!(self, block_data, "return on cleanup block") + } + } + TerminatorKind::TailCall { .. } => { + if is_cleanup { + span_mirbug!(self, block_data, "tailcall on cleanup block") + } + } + TerminatorKind::CoroutineDrop { .. } => { + if is_cleanup { + span_mirbug!(self, block_data, "coroutine_drop in cleanup block") + } + } + TerminatorKind::Yield { resume, drop, .. } => { + if is_cleanup { + span_mirbug!(self, block_data, "yield in cleanup block") + } + self.assert_iscleanup(block_data, resume, is_cleanup); + if let Some(drop) = drop { + self.assert_iscleanup(block_data, drop, is_cleanup); + } + } + TerminatorKind::Unreachable => {} + TerminatorKind::Drop { target, unwind, .. } + | TerminatorKind::Assert { target, unwind, .. } => { + self.assert_iscleanup(block_data, target, is_cleanup); + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); + } + TerminatorKind::Call { ref target, unwind, .. } => { + if let &Some(target) = target { + self.assert_iscleanup(block_data, target, is_cleanup); + } + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); + } + TerminatorKind::FalseEdge { real_target, imaginary_target } => { + self.assert_iscleanup(block_data, real_target, is_cleanup); + self.assert_iscleanup(block_data, imaginary_target, is_cleanup); + } + TerminatorKind::FalseUnwind { real_target, unwind } => { + self.assert_iscleanup(block_data, real_target, is_cleanup); + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); + } + TerminatorKind::InlineAsm { ref targets, unwind, .. } => { + for &target in targets { + self.assert_iscleanup(block_data, target, is_cleanup); + } + self.assert_iscleanup_unwind(block_data, unwind, is_cleanup); + } + } + } + + fn assert_iscleanup(&mut self, ctxt: &dyn fmt::Debug, bb: BasicBlock, iscleanuppad: bool) { + if self.body[bb].is_cleanup != iscleanuppad { + span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad); + } + } - self.sub_types( - src_obj, - dst_obj, - location.to_locations(), - ConstraintCategory::Cast { - is_implicit_coercion: false, - unsize_to: None, - }, - ) - .unwrap(); - } - } - _ => { - span_mirbug!( - self, - rvalue, - "Invalid PtrToPtr cast {:?} -> {:?}", - ty_from, - ty - ) - } - } - } - CastKind::Transmute => { - span_mirbug!( - self, - rvalue, - "Unexpected CastKind::Transmute, which is not permitted in Analysis MIR", - ); - } + fn assert_iscleanup_unwind( + &mut self, + ctxt: &dyn fmt::Debug, + unwind: UnwindAction, + is_cleanup: bool, + ) { + match unwind { + UnwindAction::Cleanup(unwind) => { + if is_cleanup { + span_mirbug!(self, ctxt, "unwind on cleanup block") + } + self.assert_iscleanup(ctxt, unwind, true); + } + UnwindAction::Continue => { + if is_cleanup { + span_mirbug!(self, ctxt, "unwind on cleanup block") } } + UnwindAction::Unreachable | UnwindAction::Terminate(_) => (), + } + } - Rvalue::Ref(region, _borrow_kind, borrowed_place) => { - self.add_reborrow_constraint(location, *region, borrowed_place); + fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) { + let tcx = self.tcx(); + + // Erase the regions from `ty` to get a global type. The + // `Sized` bound in no way depends on precise regions, so this + // shouldn't affect `is_sized`. + let erased_ty = tcx.erase_regions(ty); + // FIXME(#132279): Using `Ty::is_sized` causes us to incorrectly handle opaques here. + if !erased_ty.is_sized(tcx, self.infcx.typing_env(self.infcx.param_env)) { + // in current MIR construction, all non-control-flow rvalue + // expressions evaluate through `as_temp` or `into` a return + // slot or local, so to find all unsized rvalues it is enough + // to check all temps, return slots and locals. + if self.reported_errors.replace((ty, span)).is_none() { + // While this is located in `nll::typeck` this error is not + // an NLL error, it's a required check to prevent creation + // of unsized rvalues in a call expression. + self.tcx().dcx().emit_err(MoveUnsized { ty, span }); } + } + } - Rvalue::BinaryOp( - BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge, - box (left, right), - ) => { - self.check_operand(left, location); - self.check_operand(right, location); + fn aggregate_field_ty( + &mut self, + ak: &AggregateKind<'tcx>, + field_index: FieldIdx, + location: Location, + ) -> Result, FieldAccessError> { + let tcx = self.tcx(); - let ty_left = left.ty(self.body, tcx); - match ty_left.kind() { - // Types with regions are comparable if they have a common super-type. - ty::RawPtr(_, _) | ty::FnPtr(..) => { - let ty_right = right.ty(self.body, tcx); - let common_ty = - self.infcx.next_ty_var(self.body.source_info(location).span); - self.sub_types( - ty_left, - common_ty, - location.to_locations(), - ConstraintCategory::CallArgument(None), - ) - .unwrap_or_else(|err| { - bug!("Could not equate type variable with {:?}: {:?}", ty_left, err) - }); - if let Err(terr) = self.sub_types( - ty_right, - common_ty, - location.to_locations(), - ConstraintCategory::CallArgument(None), - ) { - span_mirbug!( - self, - rvalue, - "unexpected comparison types {:?} and {:?} yields {:?}", - ty_left, - ty_right, - terr - ) - } - } - // For types with no regions we can just check that the - // both operands have the same type. - ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_) - if ty_left == right.ty(self.body, tcx) => {} - // Other types are compared by trait methods, not by - // `Rvalue::BinaryOp`. - _ => span_mirbug!( - self, - rvalue, - "unexpected comparison types {:?} and {:?}", - ty_left, - right.ty(self.body, tcx) - ), + match *ak { + AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => { + let def = tcx.adt_def(adt_did); + let variant = &def.variant(variant_index); + let adj_field_index = active_field_index.unwrap_or(field_index); + if let Some(field) = variant.fields.get(adj_field_index) { + Ok(self.normalize(field.ty(tcx, args), location)) + } else { + Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) } } - - Rvalue::Use(operand) | Rvalue::UnaryOp(_, operand) => { - self.check_operand(operand, location); + AggregateKind::Closure(_, args) => { + match args.as_closure().upvar_tys().get(field_index.as_usize()) { + Some(ty) => Ok(*ty), + None => Err(FieldAccessError::OutOfRange { + field_count: args.as_closure().upvar_tys().len(), + }), + } } - Rvalue::CopyForDeref(place) => { - let op = &Operand::Copy(*place); - self.check_operand(op, location); + AggregateKind::Coroutine(_, args) => { + // It doesn't make sense to look at a field beyond the prefix; + // these require a variant index, and are not initialized in + // aggregate rvalues. + match args.as_coroutine().prefix_tys().get(field_index.as_usize()) { + Some(ty) => Ok(*ty), + None => Err(FieldAccessError::OutOfRange { + field_count: args.as_coroutine().prefix_tys().len(), + }), + } } - - Rvalue::BinaryOp(_, box (left, right)) => { - self.check_operand(left, location); - self.check_operand(right, location); + AggregateKind::CoroutineClosure(_, args) => { + match args.as_coroutine_closure().upvar_tys().get(field_index.as_usize()) { + Some(ty) => Ok(*ty), + None => Err(FieldAccessError::OutOfRange { + field_count: args.as_coroutine_closure().upvar_tys().len(), + }), + } } - - Rvalue::WrapUnsafeBinder(op, ty) => { - self.check_operand(op, location); - let operand_ty = op.ty(self.body, self.tcx()); - - let ty::UnsafeBinder(binder_ty) = *ty.kind() else { - unreachable!(); - }; - let expected_ty = self.infcx.instantiate_binder_with_fresh_vars( - self.body().source_info(location).span, - BoundRegionConversionTime::HigherRankedType, - binder_ty.into(), - ); - self.sub_types( - operand_ty, - expected_ty, - location.to_locations(), - ConstraintCategory::Boring, - ) - .unwrap(); + AggregateKind::Array(ty) => Ok(ty), + AggregateKind::Tuple | AggregateKind::RawPtr(..) => { + unreachable!("This should have been covered in check_rvalues"); } - - Rvalue::RawPtr(..) - | Rvalue::ThreadLocalRef(..) - | Rvalue::Len(..) - | Rvalue::Discriminant(..) - | Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {} } } @@ -2623,30 +2538,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { tcx.predicates_of(def_id).instantiate(tcx, args) } - - #[instrument(skip(self), level = "debug")] - fn typeck_mir(&mut self) { - self.last_span = self.body.span; - debug!(?self.body.span); - - for (local, local_decl) in self.body.local_decls.iter_enumerated() { - self.check_local(local, local_decl); - } - - for (block, block_data) in self.body.basic_blocks.iter_enumerated() { - let mut location = Location { block, statement_index: 0 }; - for stmt in &block_data.statements { - if !stmt.source_info.span.is_dummy() { - self.last_span = stmt.source_info.span; - } - self.check_stmt(stmt, location); - location.statement_index += 1; - } - - self.check_terminator(block_data.terminator(), location); - self.check_iscleanup(block_data); - } - } } trait NormalizeLocation: fmt::Debug + Copy { diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index c5d2a84fba4b8..1defd3867a056 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -18,7 +18,6 @@ #![feature(rustdoc_internals)] #![feature(string_from_utf8_lossy_owned)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index dec93bbccc3ee..f622646a5d9d0 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -19,7 +19,6 @@ #![feature(rustdoc_internals)] #![feature(slice_as_array)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::any::Any; diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 32f689608f816..3710625ac12d7 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -63,7 +63,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&mut CguReuseTr }, }; - for attr in tcx.hir().attrs(rustc_hir::CRATE_HIR_ID) { + for attr in tcx.hir_attrs(rustc_hir::CRATE_HIR_ID) { ams.check_attr(attr); } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 87992ce2e11b4..9cc737d194ce7 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -475,7 +475,7 @@ pub(crate) fn start_async_codegen( ) -> OngoingCodegen { let (coordinator_send, coordinator_receive) = channel(); - let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); let crate_info = CrateInfo::new(tcx, target_cpu); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 63f2f8fa3d177..e9c886d28edf6 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -876,7 +876,7 @@ impl CrateInfo { let linked_symbols = crate_types.iter().map(|&c| (c, crate::back::linker::linked_symbols(tcx, c))).collect(); let local_crate_name = tcx.crate_name(LOCAL_CRATE); - let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); let subsystem = ast::attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 27b8be1022e74..998a4ff727e85 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -60,7 +60,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { ); } - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)); + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)); let mut codegen_fn_attrs = CodegenFnAttrs::new(); if tcx.should_inherit_track_caller(did) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; @@ -75,7 +75,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // When `no_builtins` is applied at the crate level, we should add the // `no-builtins` attribute to each function to ensure it takes effect in LTO. - let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); if no_builtins { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_BUILTINS; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 4e758bfdec394..8ad040324147f 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -14,7 +14,6 @@ #![feature(rustdoc_internals)] #![feature(trait_alias)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end //! This crate contains codegen code that is used by all codegen backends (LLVM and others). diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 607cb2e497d8d..06ee7075170ff 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -81,7 +81,7 @@ pub fn rustc_allow_const_fn_unstable( def_id: LocalDefId, feature_gate: Symbol, ) -> bool { - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(def_id)); + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); find_attr!(attrs, AttributeKind::AllowConstFnUnstable(syms) if syms.contains(&feature_gate)) } diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index ed5489652fba6..da52d60ae59fd 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -16,7 +16,6 @@ #![feature(unqualified_local_imports)] #![feature(yeet_expr)] #![warn(unqualified_local_imports)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod check_consts; diff --git a/compiler/rustc_data_structures/src/graph/tests.rs b/compiler/rustc_data_structures/src/graph/tests.rs index b69b9dbc4a8e6..e48b9686c260f 100644 --- a/compiler/rustc_data_structures/src/graph/tests.rs +++ b/compiler/rustc_data_structures/src/graph/tests.rs @@ -3,7 +3,7 @@ use std::cmp::max; use super::*; use crate::fx::FxHashMap; -pub struct TestGraph { +pub(super) struct TestGraph { num_nodes: usize, start_node: usize, successors: FxHashMap>, @@ -11,7 +11,7 @@ pub struct TestGraph { } impl TestGraph { - pub fn new(start_node: usize, edges: &[(usize, usize)]) -> Self { + pub(super) fn new(start_node: usize, edges: &[(usize, usize)]) -> Self { let mut graph = TestGraph { num_nodes: start_node + 1, start_node, diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index ea3ac46734009..f63b201742d9a 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -313,7 +313,7 @@ pub struct Error { mod helper { use super::*; - pub type ObligationTreeIdGenerator = impl Iterator; + pub(super) type ObligationTreeIdGenerator = impl Iterator; impl ObligationForest { #[cfg_attr(not(bootstrap), define_opaque(ObligationTreeIdGenerator))] pub fn new() -> ObligationForest { diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index a1cc75c498503..616a18a72ab7e 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -88,7 +88,7 @@ mod mode { // Whether thread safety might be enabled. #[inline] - pub fn might_be_dyn_thread_safe() -> bool { + pub(super) fn might_be_dyn_thread_safe() -> bool { DYN_THREAD_SAFE_MODE.load(Ordering::Relaxed) != DYN_NOT_THREAD_SAFE } diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index 1ba631b862376..8ef8a3f358569 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs @@ -46,7 +46,7 @@ pub fn parallel_guard(f: impl FnOnce(&ParallelGuard) -> R) -> R { ret } -pub fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) +fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) where A: FnOnce() -> RA, B: FnOnce() -> RB, diff --git a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs index 9c1e4cefa6923..85b21a7c8ecdf 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs @@ -7,7 +7,7 @@ use crate::stable_hasher::{HashStable, StableHasher}; /// A tag type used in [`TaggedRef`] tests. #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Tag2 { +enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index a2ddff7183e60..6e4020c6eca18 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -16,7 +16,6 @@ #![feature(result_flattening)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cmp::max; diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 828a14e707c50..16d70af7e05d8 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -268,8 +268,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { let tcx = ex.tcx(); let f = |annotation: &dyn pprust_hir::PpAnn| { let sm = sess.source_map(); - let hir_map = tcx.hir(); - let attrs = |id| hir_map.attrs(id); + let attrs = |id| tcx.hir_attrs(id); pprust_hir::print_crate( sm, tcx.hir_root_module(), diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index d53d5678832b7..dfeef5a957d69 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -6,7 +6,6 @@ #![deny(rustdoc::invalid_codeblock_attributes)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // This higher-order macro defines the error codes that are in use. It is used diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 6d02d6370fc13..066546ecf7406 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -4,7 +4,6 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(type_alias_impl_trait)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 86959b28e5381..80e43ede4453a 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -25,7 +25,6 @@ #![feature(trait_alias)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_errors; diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 777044e3f33bf..4222c9fe90616 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -13,7 +13,6 @@ #![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro as pm; diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 0b034a2ae1075..25764755a8fc9 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -15,7 +15,6 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod accepted; diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index 3ad51fa1e64d0..c6e0484b92106 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -7,7 +7,6 @@ #![feature(proc_macro_span)] #![feature(rustdoc_internals)] #![feature(track_path)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index b5774f64b66b2..c8f8fd5be0237 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -277,7 +277,6 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 270d4fbec30f8..84d369f1eddb2 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -13,7 +13,6 @@ #![feature(never_type)] #![feature(rustc_attrs)] #![feature(variant_count)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_hir; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8dc5d36175044..a266286664cc2 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -185,7 +185,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo` /// projections that would result in "inheriting lifetimes". fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let hir::OpaqueTy { origin, .. } = *tcx.hir().expect_opaque_ty(def_id); + let hir::OpaqueTy { origin, .. } = *tcx.hir_expect_opaque_ty(def_id); // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting // `async-std` (and `pub async fn` in general). @@ -785,7 +785,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_type_alias_type_params_are_used(tcx, def_id); } DefKind::ForeignMod => { - let it = tcx.hir().expect_item(def_id); + let it = tcx.hir_expect_item(def_id); let hir::ItemKind::ForeignMod { abi, items } = it.kind else { return; }; 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 c193aad2afd00..0a37a27b35bab 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1031,7 +1031,7 @@ fn report_trait_method_mismatch<'tcx>( // When the `impl` receiver is an arbitrary self type, like `self: Box`, the // span points only at the type `Box, but we want to cover the whole // argument pattern and type. - let (sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); + let (sig, body) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let span = tcx .hir_body_param_names(body) .zip(sig.decl.inputs.iter()) @@ -1051,7 +1051,7 @@ fn report_trait_method_mismatch<'tcx>( // Suggestion to change output type. We do not suggest in `async` functions // to avoid complex logic or incorrect output. if let ImplItemKind::Fn(sig, _) = - &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind + &tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).kind && !sig.header.asyncness.is_async() { let msg = "change the output type to match the trait"; @@ -1190,12 +1190,12 @@ fn extract_spans_for_error_reporting<'tcx>( ) -> (Span, Option) { let tcx = infcx.tcx; let mut impl_args = { - let (sig, _) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); + let (sig, _) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())) }; let trait_args = trait_m.def_id.as_local().map(|def_id| { - let (sig, _) = tcx.hir().expect_trait_item(def_id).expect_fn(); + let (sig, _) = tcx.hir_expect_trait_item(def_id).expect_fn(); sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())) }); @@ -1371,7 +1371,7 @@ fn compare_number_of_generics<'tcx>( spans }; let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() { - let trait_item = tcx.hir().expect_trait_item(def_id); + let trait_item = tcx.hir_expect_trait_item(def_id); let arg_spans: Vec = arg_spans(trait_.kind, trait_item.generics); let impl_trait_spans: Vec = trait_item .generics @@ -1388,7 +1388,7 @@ fn compare_number_of_generics<'tcx>( (trait_span.map(|s| vec![s]), vec![]) }; - let impl_item = tcx.hir().expect_impl_item(impl_.def_id.expect_local()); + let impl_item = tcx.hir_expect_impl_item(impl_.def_id.expect_local()); let impl_item_impl_trait_spans: Vec = impl_item .generics .params @@ -1466,7 +1466,7 @@ fn compare_number_of_method_arguments<'tcx>( .def_id .as_local() .and_then(|def_id| { - let (trait_m_sig, _) = &tcx.hir().expect_trait_item(def_id).expect_fn(); + let (trait_m_sig, _) = &tcx.hir_expect_trait_item(def_id).expect_fn(); let pos = trait_number_args.saturating_sub(1); trait_m_sig.decl.inputs.get(pos).map(|arg| { if pos == 0 { @@ -1478,7 +1478,7 @@ fn compare_number_of_method_arguments<'tcx>( }) .or_else(|| tcx.hir().span_if_local(trait_m.def_id)); - let (impl_m_sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); + let (impl_m_sig, _) = &tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let pos = impl_number_args.saturating_sub(1); let impl_span = impl_m_sig .decl @@ -1580,10 +1580,10 @@ fn compare_synthetic_generics<'tcx>( // as another generic argument let new_name = tcx.opt_item_name(trait_def_id)?; let trait_m = trait_m.def_id.as_local()?; - let trait_m = tcx.hir().expect_trait_item(trait_m); + let trait_m = tcx.hir_expect_trait_item(trait_m); let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); + let impl_m = tcx.hir_expect_impl_item(impl_m); // in case there are no generics, take the spot between the function name // and the opening paren of the argument list @@ -1613,7 +1613,7 @@ fn compare_synthetic_generics<'tcx>( err.span_label(impl_span, "expected `impl Trait`, found generic parameter"); let _: Option<_> = try { let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); + let impl_m = tcx.hir_expect_impl_item(impl_m); let (sig, _) = impl_m.expect_fn(); let input_tys = sig.decl.inputs; @@ -1855,7 +1855,7 @@ fn compare_const_predicate_entailment<'tcx>( debug!(?impl_ty, ?trait_ty); // Locate the Span containing just the type of the offending impl - let (ty, _) = tcx.hir().expect_impl_item(impl_ct_def_id).expect_const(); + let (ty, _) = tcx.hir_expect_impl_item(impl_ct_def_id).expect_const(); cause.span = ty.span; let mut diag = struct_span_code_err!( @@ -1868,7 +1868,7 @@ fn compare_const_predicate_entailment<'tcx>( let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| { // Add a label to the Span containing just the type of the const - let (ty, _) = tcx.hir().expect_trait_item(trait_ct_def_id).expect_const(); + let (ty, _) = tcx.hir_expect_trait_item(trait_ct_def_id).expect_const(); ty.span }); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a400aaa814279..fd5ffdc2d7a4a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -513,7 +513,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { continue; } - let gat_item_hir = tcx.hir().expect_trait_item(gat_def_id); + let gat_item_hir = tcx.hir_expect_trait_item(gat_def_id); debug!(?required_bounds); let param_env = tcx.param_env(gat_def_id); diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 750c09887a1e5..464ffa8711a53 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -31,7 +31,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { if used_trait_imports.contains(&id) { continue; } - let item = tcx.hir().expect_item(id); + let item = tcx.hir_expect_item(id); if item.span.is_dummy() { continue; } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index cee2f487639db..c918abe4c0755 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -82,7 +82,7 @@ fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaran _ => {} } - let impl_ = tcx.hir().expect_item(impl_did).expect_impl(); + let impl_ = tcx.hir_expect_item(impl_did).expect_impl(); Err(tcx.dcx().emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span })) } @@ -109,7 +109,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran match type_allowed_to_implement_copy(tcx, param_env, self_type, cause, impl_header.safety) { Ok(()) => Ok(()), Err(CopyImplementationError::InfringingFields(fields)) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error( tcx, fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)), @@ -119,15 +119,15 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran )) } Err(CopyImplementationError::NotAnAdt) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span })) } Err(CopyImplementationError::HasDestructor) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span })) } Err(CopyImplementationError::HasUnsafeFields) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx .dcx() .span_delayed_bug(span, format!("cannot implement `Copy` for `{}`", self_type))) @@ -157,7 +157,7 @@ fn visit_implementation_of_const_param_ty( match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, kind, cause) { Ok(()) => Ok(()), Err(ConstParamTyImplementationError::InfrigingFields(fields)) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error( tcx, fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)), @@ -167,11 +167,11 @@ fn visit_implementation_of_const_param_ty( )) } Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span })) } Err(ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(infringing_tys)) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error( tcx, infringing_tys.into_iter().map(|(ty, reason)| (span, ty, reason)), @@ -181,7 +181,7 @@ fn visit_implementation_of_const_param_ty( )) } Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnUnsized { span })) } } @@ -526,7 +526,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( note: true, })); } else if diff_fields.len() > 1 { - let item = tcx.hir().expect_item(impl_did); + let item = tcx.hir_expect_item(impl_did); let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(t), .. }) = &item.kind { t.path.span } else { diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index dbf7a7378f5ab..0b7fc44460ead 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -376,7 +376,7 @@ fn emit_orphan_check_error<'tcx>( ) -> ErrorGuaranteed { match err { traits::OrphanCheckErr::NonLocalInputType(tys) => { - let item = tcx.hir().expect_item(impl_def_id); + let item = tcx.hir_expect_item(impl_def_id); let impl_ = item.expect_impl(); let hir_trait_ref = impl_.of_trait.as_ref().unwrap(); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 49523912b14d3..cfb6cf8a28792 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -469,8 +469,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => { let item = self .tcx - .hir() - .expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); + .hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); match &item.kind { hir::ItemKind::Enum(_, generics) | hir::ItemKind::Struct(_, generics) @@ -1143,7 +1142,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { } fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); let (is_alias, is_auto, safety, items) = match item.kind { hir::ItemKind::Trait(is_auto, safety, .., items) => { @@ -1342,7 +1341,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn ), ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => { - let abi = tcx.hir().get_foreign_abi(hir_id); + let abi = tcx.hir_get_foreign_abi(hir_id); compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety()) } @@ -1597,7 +1596,7 @@ pub fn suggest_impl_trait<'tcx>( fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option> { let icx = ItemCtxt::new(tcx, def_id); - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); let impl_ = item.expect_impl(); impl_.of_trait.as_ref().map(|ast_trait_ref| { let selfty = tcx.type_of(def_id).instantiate_identity(); diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 4debd3977f50a..7cbd31de6bab2 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -13,7 +13,7 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { for id in tcx.hir_crate_items(()).opaques() { if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } = - tcx.hir().expect_opaque_ty(id).origin + tcx.hir_expect_opaque_ty(id).origin && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 6936544838c81..16caa4f6874c7 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -480,5 +480,5 @@ pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> } } } - HasTait.visit_ty_unambig(tcx.hir().expect_item(def_id).expect_ty_alias().0).is_break() + HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().0).is_break() } diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 4dbdfa3d85a9b..78b20f9897cc1 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -404,11 +404,16 @@ fn check_constraints<'tcx>( }; if let Some(local_sig_id) = sig_id.as_local() - && tcx.hir().opt_delegation_sig_id(local_sig_id).is_some() + && tcx.hir_opt_delegation_sig_id(local_sig_id).is_some() { emit("recursive delegation is not supported yet"); } + if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic { + // See issue #127443 for explanation. + emit("delegation to C-variadic functions is not allowed"); + } + ret } @@ -416,7 +421,7 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, ) -> &'tcx [Ty<'tcx>] { - let sig_id = tcx.hir().opt_delegation_sig_id(def_id).unwrap(); + let sig_id = tcx.hir_opt_delegation_sig_id(def_id).unwrap(); let caller_sig = tcx.fn_sig(sig_id); if let Err(err) = check_constraints(tcx, def_id, sig_id) { let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1; 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 5f91f1d7b3e1f..8fff6eb9f6e4b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -370,7 +370,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { #[instrument(level = "debug", skip(self), ret)] pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> { let tcx = self.tcx(); - let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id)); + let lifetime_name = |def_id| tcx.hir_name(tcx.local_def_id_to_hir_id(def_id)); match resolved { rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static, diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 50b0e32b95ebf..26a20690a95c4 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -73,7 +73,6 @@ This API is completely unstable and subject to change. #![feature(slice_partition_dedup)] #![feature(try_blocks)] #![feature(unwrap_infallible)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // These are used by Clippy. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index ae624fc253f2f..3067766fb4d73 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -3,7 +3,6 @@ // tidy-alphabetical-start #![recursion_limit = "256"] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::Cell; diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 5e00161f693f6..2a24d626ac357 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -799,7 +799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Emit a different diagnostic for local variables, as they are not // type definitions themselves, but rather variables *of* that type. Res::Local(hir_id) => { - err.arg("local_name", self.tcx.hir().name(hir_id)); + err.arg("local_name", self.tcx.hir_name(hir_id)); Some(fluent_generated::hir_typeck_invalid_local) } Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7e4026db738d7..7c6bb495be375 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -298,7 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Combine the diverging and has_error flags. self.diverges.set(self.diverges.get() | old_diverges); - debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id)); + debug!("type of {} is...", self.tcx.hir_id_to_string(expr.hir_id)); debug!("... {:?}, expected is {:?}", ty, expected); ty diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 9ff7eeb23688c..63e4a8fb44bda 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1235,7 +1235,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.cx.tainted_by_errors()?; bug!( "no type for node {} in mem_categorization", - self.cx.tcx().hir().node_to_string(id) + self.cx.tcx().hir_id_to_string(id) ); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index da2d657942300..c82f7a91168af 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -140,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> { self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| { - span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid)) + span_bug!(span, "no type for local variable {}", self.tcx.hir_id_to_string(nid)) }) } @@ -559,11 +559,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(&t) => t, None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e), None => { - bug!( - "no type for node {} in fcx {}", - self.tcx.hir().node_to_string(id), - self.tag() - ); + bug!("no type for node {} in fcx {}", self.tcx.hir_id_to_string(id), self.tag()); } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 35a3491f7c089..37aaaed5477dd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -613,7 +613,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .take(4) .map(|(var_hir_id, upvar)| { - let var_name = self.tcx.hir().name(*var_hir_id).to_string(); + let var_name = self.tcx.hir_name(*var_hir_id).to_string(); let msg = format!("`{var_name}` captured here"); (upvar.span, msg) }) diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 8b9c2b4a6ca0f..263fb84206e0b 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -8,7 +8,6 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod _match; diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index 69d7a6c97cb36..72f8793d78399 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs @@ -363,7 +363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let import_items: Vec<_> = applicable_trait .import_ids .iter() - .map(|&import_id| self.tcx.hir().expect_item(import_id)) + .map(|&import_id| self.tcx.hir_expect_item(import_id)) .collect(); // Find an identifier with which this trait was imported (note that `_` doesn't count). diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index f87e5b5202ab5..ee01d78965d5c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -2344,7 +2344,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return false; }; let hir_id = self.fcx.tcx.local_def_id_to_hir_id(local_def_id); - let attrs = self.fcx.tcx.hir().attrs(hir_id); + let attrs = self.fcx.tcx.hir_attrs(hir_id); for attr in attrs { if sym::doc == attr.name_or_empty() { } else if sym::rustc_confusables == attr.name_or_empty() { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index cb1e89fb9e593..1a1540f505d37 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -791,7 +791,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Ok(pick) = self.lookup_probe_for_diagnostic( item_name, Ty::new_ref(tcx, ty::Region::new_error_misc(tcx), ty, ptr_mutbl), - self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)), + self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)), ProbeScope::TraitsInScope, None, ) @@ -834,8 +834,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let SelfSource::MethodCall(rcvr_expr) = source { self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| { - let call_expr = - self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)); + let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)); let probe = self.lookup_probe_for_diagnostic( item_name, output_ty, @@ -2373,7 +2372,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } else { - let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id)); + let call_expr = tcx.hir_expect_expr(tcx.parent_hir_id(expr.hir_id)); if let Some(span) = call_expr.span.trim_start(item_name.span) { err.span_suggestion( @@ -2680,7 +2679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mod_id, expr.hir_id, ) { - let call_expr = self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id)); + let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(expr.hir_id)); let lang_items = self.tcx.lang_items(); let never_mention_traits = [ @@ -2757,7 +2756,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let SelfSource::MethodCall(expr) = source else { return; }; - let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id)); + let call_expr = tcx.hir_expect_expr(tcx.parent_hir_id(expr.hir_id)); let ty::Adt(kind, args) = actual.kind() else { return; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index f570d0d8a0d30..37f3786c00abc 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -781,7 +781,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id, base => bug!("Expected upvar, found={:?}", base), }; - let var_ident = self.tcx.hir().ident(var_hir_id); + let var_ident = self.tcx.hir_ident(var_hir_id); let Some(min_cap_list) = root_var_min_capture_list.get_mut(&var_hir_id) else { let mutability = self.determine_capture_mutability(&typeck_results, &place); @@ -988,13 +988,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => { let cause_span = self.tcx.hir().span(*capture_expr_id); lint.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`", - self.tcx.hir().name(*var_hir_id), + self.tcx.hir_name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span } => { lint.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect", - self.tcx.hir().name(*var_hir_id), + self.tcx.hir_name(*var_hir_id), )); } @@ -1009,13 +1009,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { lint.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure", - self.tcx.hir().name(*var_hir_id), + self.tcx.hir_name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span: _ } => { lint.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure", - v = self.tcx.hir().name(*var_hir_id), + v = self.tcx.hir_name(*var_hir_id), )); } } @@ -1026,7 +1026,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // not capturing something anymore cannot cause a trait to fail to be implemented: match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { - let var_name = self.tcx.hir().name(*var_hir_id); + let var_name = self.tcx.hir_name(*var_hir_id); lint.span_label(closure_head_span, format!("\ in Rust 2018, this closure implements {missing_trait} \ as `{var_name}` implements {missing_trait}, but in Rust 2021, \ @@ -2300,7 +2300,7 @@ fn construct_capture_info_string<'tcx>( } fn var_name(tcx: TyCtxt<'_>, var_hir_id: HirId) -> Symbol { - tcx.hir().name(var_hir_id) + tcx.hir_name(var_hir_id) } #[instrument(level = "debug", skip(tcx))] diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 8f2ca6babea88..1b2056f541f3e 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -123,7 +123,7 @@ impl<'tcx> IfThisChanged<'tcx> { fn process_attrs(&mut self, def_id: LocalDefId) { let def_path_hash = self.tcx.def_path_hash(def_id.to_def_id()); let hir_id = self.tcx.local_def_id_to_hir_id(def_id); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { if attr.has_name(sym::rustc_if_this_changed) { let dep_node_interned = self.argument(attr); diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 563ed7614c609..299ee4876389c 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -7,7 +7,6 @@ #![doc(rust_logo)] #![feature(file_buffered)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod assert_dep_graph; diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 3441a5f65c785..cc680838e7e7b 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -4,7 +4,6 @@ #![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))] #![cfg_attr(feature = "nightly", feature(new_range_api))] #![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod bit_set; diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs index 67ec776113399..f0b58eabbff9a 100644 --- a/compiler/rustc_index_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs @@ -305,7 +305,7 @@ impl Parse for Newtype { } } -pub fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub(crate) fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as Newtype); input.0.into() } diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index a04b2bb2b08b5..ece18f4ea64ee 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -24,7 +24,6 @@ #![feature(let_chains)] #![feature(rustdoc_internals)] #![recursion_limit = "512"] // For rustdoc -#![warn(unreachable_pub)] // tidy-alphabetical-end mod errors; diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 54cd341698f0b..67e0be93523d9 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -4,7 +4,6 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod callbacks; diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index 00600abb5f1e3..a2c1f1dbeda6b 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs @@ -8,7 +8,7 @@ fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option { let mut decls = None; for id in tcx.hir_free_items() { - let attrs = tcx.hir().attrs(id.hir_id()); + let attrs = tcx.hir_attrs(id.hir_id()); if attr::contains_name(attrs, sym::rustc_proc_macro_decls) { decls = Some(id.owner_id.def_id); } diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index bf18845a0830d..61638e45253fd 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -23,7 +23,6 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod cursor; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f7be37dc4a2c3..918a42f304780 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -419,7 +419,7 @@ impl MissingDoc { return; } - let attrs = cx.tcx.hir().attrs(cx.tcx.local_def_id_to_hir_id(def_id)); + let attrs = cx.tcx.hir_attrs(cx.tcx.local_def_id_to_hir_id(def_id)); let has_doc = attrs.iter().any(has_doc); if !has_doc { cx.emit_span_lint( @@ -997,7 +997,7 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); let check_no_mangle_on_generic_fn = |no_mangle_attr: &hir::Attribute, impl_generics: Option<&hir::Generics<'_>>, generics: &hir::Generics<'_>, @@ -1050,7 +1050,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { for it in *items { if let hir::AssocItemKind::Fn { .. } = it.kind { if let Some(no_mangle_attr) = - attr::find_by_name(cx.tcx.hir().attrs(it.id.hir_id()), sym::no_mangle) + attr::find_by_name(cx.tcx.hir_attrs(it.id.hir_id()), sym::no_mangle) { check_no_mangle_on_generic_fn( no_mangle_attr, diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 9ca148e1f2549..4c2b82a9a23a6 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -38,7 +38,7 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { } LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { // We are an `eval_always` query, so looking at the attribute's `AttrId` is ok. - let attr_id = tcx.hir().attrs(hir_id)[attr_index as usize].id(); + let attr_id = tcx.hir_attrs(hir_id)[attr_index as usize].id(); (attr_id, lint_index) } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 23d6efa050836..852bb01c09655 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -48,7 +48,7 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { where F: FnOnce(&mut Self), { - let attrs = self.context.tcx.hir().attrs(id); + let attrs = self.context.tcx.hir_attrs(id); let prev = self.context.last_node_with_lint_attrs; self.context.last_node_with_lint_attrs = id; debug!("late context: enter_attrs({:?})", attrs); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 4ede9b4408798..aa6eef906ea42 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -152,7 +152,7 @@ fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { #[instrument(level = "trace", skip(tcx), ret)] fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap { let store = unerased_lint_store(tcx.sess); - let attrs = tcx.hir_attrs(owner); + let attrs = tcx.hir_attr_map(owner); let mut levels = LintLevelsBuilder { sess: tcx.sess, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7018774e5c6bc..35867d8c9efef 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -32,7 +32,6 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod async_closures; diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 49f9ad39780a3..722779d326891 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -342,8 +342,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name { Some(Ident::from_str(name)) } else { - ast::attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name) - .and_then(|attr| { + ast::attr::find_by_name(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), sym::crate_name).and_then( + |attr| { if let Attribute::Unparsed(n) = attr && let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: lit }, .. } = n.as_ref() @@ -371,7 +371,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { } else { None } - }) + }, + ) }; if let Some(ident) = &crate_ident { @@ -500,7 +501,7 @@ impl NonUpperCaseGlobals { impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); match it.kind { hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => { NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index fcadbfc3c4a7e..6f3c32af5ef59 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1589,7 +1589,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations { fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, it: &hir::ForeignItem<'tcx>) { let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Declaration }; - let abi = cx.tcx.hir().get_foreign_abi(it.hir_id()); + let abi = cx.tcx.hir_get_foreign_abi(it.hir_id()); match it.kind { hir::ForeignItemKind::Fn(sig, _, _) => { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index e564235c41a5e..46b4b1d438386 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -1,7 +1,3 @@ -// tidy-alphabetical-start -#![warn(unreachable_pub)] -// tidy-alphabetical-end - use rustc_abi::ExternAbi; use rustc_ast::AttrId; use rustc_ast::attr::AttributeExt; diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index eda9b2b1fc092..68058250a2671 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -4,7 +4,6 @@ #![doc(rust_logo)] #![feature(extern_types)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::RefCell; diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 34fc0f00320c0..44ba064dd824c 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -6,7 +6,6 @@ #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] #![feature(proc_macro_tracked_env)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 582c2215d92e1..be31aa629c86e 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -84,7 +84,7 @@ pub(crate) fn calculate(tcx: TyCtxt<'_>) -> Dependencies { fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { let sess = &tcx.sess; - if !sess.opts.output_types.should_codegen() { + if !sess.opts.output_types.should_link() { return IndexVec::new(); } diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index ebcc0efd5a67a..8898c5824fa25 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -15,7 +15,6 @@ #![feature(proc_macro_internals)] #![feature(rustdoc_internals)] #![feature(trusted_len)] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 88a88847e6b8b..57c941976e44b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1357,8 +1357,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { features: &tcx.features(), }; let attr_iter = tcx - .hir() - .attrs(tcx.local_def_id_to_hir_id(def_id)) + .hir_attrs(tcx.local_def_id_to_hir_id(def_id)) .iter() .filter(|attr| analyze_attr(*attr, &mut state)); @@ -1839,7 +1838,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_macro(&mut self, def_id: LocalDefId) { let tcx = self.tcx; - let hir::ItemKind::Macro(macro_def, _) = tcx.hir().expect_item(def_id).kind else { bug!() }; + let hir::ItemKind::Macro(macro_def, _) = tcx.hir_expect_item(def_id).kind else { bug!() }; self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules); record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); } @@ -1918,11 +1917,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for &proc_macro in &tcx.resolutions(()).proc_macros { let id = proc_macro; let proc_macro = tcx.local_def_id_to_hir_id(proc_macro); - let mut name = hir.name(proc_macro); + let mut name = tcx.hir_name(proc_macro); let span = hir.span(proc_macro); // Proc-macros may have attributes like `#[allow_internal_unstable]`, // so downstream crates need access to them. - let attrs = hir.attrs(proc_macro); + let attrs = tcx.hir_attrs(proc_macro); let macro_kind = if ast::attr::contains_name(attrs, sym::proc_macro) { MacroKind::Bang } else if ast::attr::contains_name(attrs, sym::proc_macro_attribute) { diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index c85af81ee25bd..73c0af84a9fde 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -275,7 +275,7 @@ impl<'tcx> TyCtxt<'tcx> { span_bug!( self.hir().span(hir_id), "body_owned_by: {} has no associated body", - self.hir().node_to_string(hir_id) + self.hir_id_to_string(hir_id) ); }) } @@ -374,7 +374,7 @@ impl<'tcx> TyCtxt<'tcx> { /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. pub fn hir_krate_attrs(self) -> &'tcx [Attribute] { - self.hir().attrs(CRATE_HIR_ID) + self.hir_attrs(CRATE_HIR_ID) } pub fn hir_rustc_coherence_is_core(self) -> bool { @@ -674,104 +674,178 @@ impl<'tcx> TyCtxt<'tcx> { } } } -} -impl<'hir> Map<'hir> { - pub fn get_foreign_abi(self, hir_id: HirId) -> ExternAbi { - let parent = self.tcx.hir_get_parent_item(hir_id); + /// Get a representation of this `id` for debugging purposes. + /// NOTE: Do NOT use this in diagnostics! + pub fn hir_id_to_string(self, id: HirId) -> String { + let path_str = |def_id: LocalDefId| self.def_path_str(def_id); + + let span_str = || { + self.sess.source_map().span_to_snippet(Map { tcx: self }.span(id)).unwrap_or_default() + }; + let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); + + match self.hir_node(id) { + Node::Item(item) => { + let item_str = match item.kind { + ItemKind::ExternCrate(..) => "extern crate", + ItemKind::Use(..) => "use", + ItemKind::Static(..) => "static", + ItemKind::Const(..) => "const", + ItemKind::Fn { .. } => "fn", + ItemKind::Macro(..) => "macro", + ItemKind::Mod(..) => "mod", + ItemKind::ForeignMod { .. } => "foreign mod", + ItemKind::GlobalAsm { .. } => "global asm", + ItemKind::TyAlias(..) => "ty", + ItemKind::Enum(..) => "enum", + ItemKind::Struct(..) => "struct", + ItemKind::Union(..) => "union", + ItemKind::Trait(..) => "trait", + ItemKind::TraitAlias(..) => "trait alias", + ItemKind::Impl { .. } => "impl", + }; + format!("{id} ({item_str} {})", path_str(item.owner_id.def_id)) + } + Node::ForeignItem(item) => { + format!("{id} (foreign item {})", path_str(item.owner_id.def_id)) + } + Node::ImplItem(ii) => { + let kind = match ii.kind { + ImplItemKind::Const(..) => "associated constant", + ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { + ImplicitSelfKind::None => "associated function", + _ => "method", + }, + ImplItemKind::Type(_) => "associated type", + }; + format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id)) + } + Node::TraitItem(ti) => { + let kind = match ti.kind { + TraitItemKind::Const(..) => "associated constant", + TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { + ImplicitSelfKind::None => "associated function", + _ => "trait method", + }, + TraitItemKind::Type(..) => "associated type", + }; + + format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id)) + } + Node::Variant(variant) => { + format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id)) + } + Node::Field(field) => { + format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id)) + } + Node::AnonConst(_) => node_str("const"), + Node::ConstBlock(_) => node_str("const"), + Node::ConstArg(_) => node_str("const"), + Node::Expr(_) => node_str("expr"), + Node::ExprField(_) => node_str("expr field"), + Node::Stmt(_) => node_str("stmt"), + Node::PathSegment(_) => node_str("path segment"), + Node::Ty(_) => node_str("type"), + Node::AssocItemConstraint(_) => node_str("assoc item constraint"), + Node::TraitRef(_) => node_str("trait ref"), + Node::OpaqueTy(_) => node_str("opaque type"), + Node::Pat(_) => node_str("pat"), + Node::TyPat(_) => node_str("pat ty"), + Node::PatField(_) => node_str("pattern field"), + Node::PatExpr(_) => node_str("pattern literal"), + Node::Param(_) => node_str("param"), + Node::Arm(_) => node_str("arm"), + Node::Block(_) => node_str("block"), + Node::Infer(_) => node_str("infer"), + Node::LetStmt(_) => node_str("local"), + Node::Ctor(ctor) => format!( + "{id} (ctor {})", + ctor.ctor_def_id().map_or("".into(), |def_id| path_str(def_id)), + ), + Node::Lifetime(_) => node_str("lifetime"), + Node::GenericParam(param) => { + format!("{id} (generic_param {})", path_str(param.def_id)) + } + Node::Crate(..) => String::from("(root_crate)"), + Node::WherePredicate(_) => node_str("where predicate"), + Node::Synthetic => unreachable!(), + Node::Err(_) => node_str("error"), + Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), + } + } + + pub fn hir_get_foreign_abi(self, hir_id: HirId) -> ExternAbi { + let parent = self.hir_get_parent_item(hir_id); if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = - self.tcx.hir_owner_node(parent) + self.hir_owner_node(parent) { return *abi; } bug!( "expected foreign mod or inlined parent, found {}", - self.node_to_string(HirId::make_owner(parent.def_id)) + self.hir_id_to_string(HirId::make_owner(parent.def_id)) ) } - pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> { - match self.tcx.expect_hir_owner_node(id) { + pub fn hir_expect_item(self, id: LocalDefId) -> &'tcx Item<'tcx> { + match self.expect_hir_owner_node(id) { OwnerNode::Item(item) => item, - _ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))), + _ => bug!("expected item, found {}", self.hir_id_to_string(HirId::make_owner(id))), } } - pub fn expect_impl_item(self, id: LocalDefId) -> &'hir ImplItem<'hir> { - match self.tcx.expect_hir_owner_node(id) { + pub fn hir_expect_impl_item(self, id: LocalDefId) -> &'tcx ImplItem<'tcx> { + match self.expect_hir_owner_node(id) { OwnerNode::ImplItem(item) => item, - _ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))), + _ => bug!("expected impl item, found {}", self.hir_id_to_string(HirId::make_owner(id))), } } - pub fn expect_trait_item(self, id: LocalDefId) -> &'hir TraitItem<'hir> { - match self.tcx.expect_hir_owner_node(id) { + pub fn hir_expect_trait_item(self, id: LocalDefId) -> &'tcx TraitItem<'tcx> { + match self.expect_hir_owner_node(id) { OwnerNode::TraitItem(item) => item, - _ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))), - } - } - - pub fn get_fn_output(self, def_id: LocalDefId) -> Option<&'hir FnRetTy<'hir>> { - Some(&self.tcx.opt_hir_owner_node(def_id)?.fn_decl()?.output) - } - - pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> { - match self.tcx.hir_node(id) { - Node::Variant(variant) => variant, - _ => bug!("expected variant, found {}", self.node_to_string(id)), - } - } - - pub fn expect_field(self, id: HirId) -> &'hir FieldDef<'hir> { - match self.tcx.hir_node(id) { - Node::Field(field) => field, - _ => bug!("expected field, found {}", self.node_to_string(id)), - } - } - - pub fn expect_foreign_item(self, id: OwnerId) -> &'hir ForeignItem<'hir> { - match self.tcx.hir_owner_node(id) { - OwnerNode::ForeignItem(item) => item, _ => { - bug!( - "expected foreign item, found {}", - self.node_to_string(HirId::make_owner(id.def_id)) - ) + bug!("expected trait item, found {}", self.hir_id_to_string(HirId::make_owner(id))) } } } + pub fn hir_get_fn_output(self, def_id: LocalDefId) -> Option<&'tcx FnRetTy<'tcx>> { + Some(&self.opt_hir_owner_node(def_id)?.fn_decl()?.output) + } + #[track_caller] - pub fn expect_opaque_ty(self, id: LocalDefId) -> &'hir OpaqueTy<'hir> { - match self.tcx.hir_node_by_def_id(id) { + pub fn hir_expect_opaque_ty(self, id: LocalDefId) -> &'tcx OpaqueTy<'tcx> { + match self.hir_node_by_def_id(id) { Node::OpaqueTy(opaq) => opaq, _ => { bug!( "expected opaque type definition, found {}", - self.node_to_string(self.tcx.local_def_id_to_hir_id(id)) + self.hir_id_to_string(self.local_def_id_to_hir_id(id)) ) } } } - pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> { - match self.tcx.hir_node(id) { + pub fn hir_expect_expr(self, id: HirId) -> &'tcx Expr<'tcx> { + match self.hir_node(id) { Node::Expr(expr) => expr, - _ => bug!("expected expr, found {}", self.node_to_string(id)), + _ => bug!("expected expr, found {}", self.hir_id_to_string(id)), } } - pub fn opt_delegation_sig_id(self, def_id: LocalDefId) -> Option { - self.tcx.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id() + pub fn hir_opt_delegation_sig_id(self, def_id: LocalDefId) -> Option { + self.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id() } #[inline] - fn opt_ident(self, id: HirId) -> Option { - match self.tcx.hir_node(id) { + fn hir_opt_ident(self, id: HirId) -> Option { + match self.hir_node(id) { Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::span`. - Node::Ctor(..) => match self.tcx.parent_hir_node(id) { + Node::Ctor(..) => match self.parent_hir_node(id) { Node::Item(item) => Some(item.ident), Node::Variant(variant) => Some(variant.ident), _ => unreachable!(), @@ -781,30 +855,32 @@ impl<'hir> Map<'hir> { } #[inline] - pub(super) fn opt_ident_span(self, id: HirId) -> Option { - self.opt_ident(id).map(|ident| ident.span) + pub(super) fn hir_opt_ident_span(self, id: HirId) -> Option { + self.hir_opt_ident(id).map(|ident| ident.span) } #[inline] - pub fn ident(self, id: HirId) -> Ident { - self.opt_ident(id).unwrap() + pub fn hir_ident(self, id: HirId) -> Ident { + self.hir_opt_ident(id).unwrap() } #[inline] - pub fn opt_name(self, id: HirId) -> Option { - self.opt_ident(id).map(|ident| ident.name) + pub fn hir_opt_name(self, id: HirId) -> Option { + self.hir_opt_ident(id).map(|ident| ident.name) } - pub fn name(self, id: HirId) -> Symbol { - self.opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.node_to_string(id))) + pub fn hir_name(self, id: HirId) -> Symbol { + self.hir_opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.hir_id_to_string(id))) } /// Given a node ID, gets a list of attributes associated with the AST /// corresponding to the node-ID. - pub fn attrs(self, id: HirId) -> &'hir [Attribute] { - self.tcx.hir_attrs(id.owner).get(id.local_id) + pub fn hir_attrs(self, id: HirId) -> &'tcx [Attribute] { + self.hir_attr_map(id.owner).get(id.local_id) } +} +impl<'hir> Map<'hir> { /// Gets the span of the definition of the specified HIR node. /// This is used by `tcx.def_span`. pub fn span(self, hir_id: HirId) -> Span { @@ -977,12 +1053,6 @@ impl<'hir> Map<'hir> { } } - /// Get a representation of this `id` for debugging purposes. - /// NOTE: Do NOT use this in diagnostics! - pub fn node_to_string(self, id: HirId) -> String { - hir_id_to_string(self, id) - } - /// Returns the HirId of `N` in `struct Foo` when /// called with the HirId for the `{ ... }` anon const pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option { @@ -1147,102 +1217,6 @@ fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> { upstream_crates } -fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { - let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id); - - let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default(); - let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); - - match map.tcx.hir_node(id) { - Node::Item(item) => { - let item_str = match item.kind { - ItemKind::ExternCrate(..) => "extern crate", - ItemKind::Use(..) => "use", - ItemKind::Static(..) => "static", - ItemKind::Const(..) => "const", - ItemKind::Fn { .. } => "fn", - ItemKind::Macro(..) => "macro", - ItemKind::Mod(..) => "mod", - ItemKind::ForeignMod { .. } => "foreign mod", - ItemKind::GlobalAsm { .. } => "global asm", - ItemKind::TyAlias(..) => "ty", - ItemKind::Enum(..) => "enum", - ItemKind::Struct(..) => "struct", - ItemKind::Union(..) => "union", - ItemKind::Trait(..) => "trait", - ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl { .. } => "impl", - }; - format!("{id} ({item_str} {})", path_str(item.owner_id.def_id)) - } - Node::ForeignItem(item) => { - format!("{id} (foreign item {})", path_str(item.owner_id.def_id)) - } - Node::ImplItem(ii) => { - let kind = match ii.kind { - ImplItemKind::Const(..) => "associated constant", - ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { - ImplicitSelfKind::None => "associated function", - _ => "method", - }, - ImplItemKind::Type(_) => "associated type", - }; - format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id)) - } - Node::TraitItem(ti) => { - let kind = match ti.kind { - TraitItemKind::Const(..) => "associated constant", - TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { - ImplicitSelfKind::None => "associated function", - _ => "trait method", - }, - TraitItemKind::Type(..) => "associated type", - }; - - format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id)) - } - Node::Variant(variant) => { - format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id)) - } - Node::Field(field) => { - format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id)) - } - Node::AnonConst(_) => node_str("const"), - Node::ConstBlock(_) => node_str("const"), - Node::ConstArg(_) => node_str("const"), - Node::Expr(_) => node_str("expr"), - Node::ExprField(_) => node_str("expr field"), - Node::Stmt(_) => node_str("stmt"), - Node::PathSegment(_) => node_str("path segment"), - Node::Ty(_) => node_str("type"), - Node::AssocItemConstraint(_) => node_str("assoc item constraint"), - Node::TraitRef(_) => node_str("trait ref"), - Node::OpaqueTy(_) => node_str("opaque type"), - Node::Pat(_) => node_str("pat"), - Node::TyPat(_) => node_str("pat ty"), - Node::PatField(_) => node_str("pattern field"), - Node::PatExpr(_) => node_str("pattern literal"), - Node::Param(_) => node_str("param"), - Node::Arm(_) => node_str("arm"), - Node::Block(_) => node_str("block"), - Node::Infer(_) => node_str("infer"), - Node::LetStmt(_) => node_str("local"), - Node::Ctor(ctor) => format!( - "{id} (ctor {})", - ctor.ctor_def_id().map_or("".into(), |def_id| path_str(def_id)), - ), - Node::Lifetime(_) => node_str("lifetime"), - Node::GenericParam(param) => { - format!("{id} (generic_param {})", path_str(param.def_id)) - } - Node::Crate(..) => String::from("(root_crate)"), - Node::WherePredicate(_) => node_str("where predicate"), - Node::Synthetic => unreachable!(), - Node::Err(_) => node_str("error"), - Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), - } -} - pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> ModuleItems { let mut collector = ItemCollector::new(tcx, false); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 6071a58367ed1..68b9a4f56b96d 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -202,13 +202,13 @@ pub fn provide(providers: &mut Providers) { } }) }; - providers.hir_attrs = |tcx, id| { + providers.hir_attr_map = |tcx, id| { tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs) }; providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id)); providers.def_ident_span = |tcx, def_id| { let hir_id = tcx.local_def_id_to_hir_id(def_id); - tcx.hir().opt_ident_span(hir_id) + tcx.hir_opt_ident_span(hir_id) }; providers.fn_arg_names = |tcx, def_id| { let hir = tcx.hir(); diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 48ea7df5c23fd..8fe2cc7101ba3 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -61,7 +61,6 @@ #![feature(try_trait_v2_yeet)] #![feature(type_alias_impl_trait)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end #[cfg(test)] diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f880b1364c2cd..573f7895da2e2 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -653,7 +653,10 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io: write!(w, "static mut ")? } (_, _) if is_function => write!(w, "fn ")?, - (DefKind::AnonConst | DefKind::InlineConst, _) => {} // things like anon const, not an item + // things like anon const, not an item + (DefKind::AnonConst | DefKind::InlineConst, _) => {} + // `global_asm!` have fake bodies, which we may dump after mir-build + (DefKind::GlobalAsm, _) => {} _ => bug!("Unexpected def kind {:?}", kind), } @@ -1200,7 +1203,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { && let Some(upvars) = tcx.upvars_mentioned(def_id) { for (&var_id, place) in iter::zip(upvars.keys(), places) { - let var_name = tcx.hir().name(var_id); + let var_name = tcx.hir_name(var_id); struct_fmt.field(var_name.as_str(), place); } } else { @@ -1221,7 +1224,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { && let Some(upvars) = tcx.upvars_mentioned(def_id) { for (&var_id, place) in iter::zip(upvars.keys(), places) { - let var_name = tcx.hir().name(var_id); + let var_name = tcx.hir_name(var_id); struct_fmt.field(var_name.as_str(), place); } } else { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index c8708857565cd..781a898a6e997 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -198,7 +198,7 @@ rustc_queries! { /// /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. - query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { + query hir_attr_map(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } feedable } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 53f233f20eb94..7e6151745e2f8 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -980,12 +980,9 @@ pub enum CodegenObligationError { /// overflow bug, since I believe this is the only case /// where ambiguity can result. Ambiguity, - /// This can trigger when we probe for the source of a `'static` lifetime requirement - /// on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound. - /// This can also trigger when we have a global bound that is not actually satisfied, - /// but was included during typeck due to the trivial_bounds feature. + /// This can trigger when we have a global bound that is not actually satisfied + /// due to trivial bounds. Unimplemented, - FulfillmentError, /// The selected impl has unconstrained generic parameters. This will emit an error /// during impl WF checking. UnconstrainedParam(ErrorGuaranteed), diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 9ce5373b03118..8e54a9d487d92 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -72,7 +72,7 @@ impl OverlapMode { .as_local() .into_iter() .flat_map(|local_def_id| { - tcx.hir().attrs(tcx.local_def_id_to_hir_id(local_def_id)) + tcx.hir_attrs(tcx.local_def_id_to_hir_id(local_def_id)) }) .find(|attr| attr.has_name(sym::rustc_strict_coherence)) .map(|attr| attr.span()); diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 5d9b1ddfa38ea..703b6ce92471f 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -296,7 +296,7 @@ pub struct CaptureInfo { pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) -> String { let mut curr_string: String = match place.base { - HirPlaceBase::Upvar(upvar_id) => tcx.hir().name(upvar_id.var_path.hir_id).to_string(), + HirPlaceBase::Upvar(upvar_id) => tcx.hir_name(upvar_id.var_path.hir_id).to_string(), _ => bug!("Capture_information should only contain upvars"), }; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index edba2a2530f68..544a6cb64f31b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1299,7 +1299,7 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> { ), bodies, }))); - self.feed_owner_id().hir_attrs(attrs); + self.feed_owner_id().hir_attr_map(attrs); } } @@ -2214,7 +2214,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns the origin of the opaque type `def_id`. #[instrument(skip(self), level = "trace", ret)] pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin { - self.hir().expect_opaque_ty(def_id).origin + self.hir_expect_opaque_ty(def_id).origin } pub fn finish(self) { @@ -3118,9 +3118,11 @@ impl<'tcx> TyCtxt<'tcx> { pub fn late_bound_vars(self, id: HirId) -> &'tcx List { self.mk_bound_variable_kinds( - &self.late_bound_vars_map(id.owner).get(&id.local_id).cloned().unwrap_or_else(|| { - bug!("No bound vars found for {}", self.hir().node_to_string(id)) - }), + &self + .late_bound_vars_map(id.owner) + .get(&id.local_id) + .cloned() + .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))), ) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 97cfe5946af15..ad9d32fd6c152 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1696,7 +1696,7 @@ impl<'tcx> TyCtxt<'tcx> { // FIXME(@lcnr): Remove this function. pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [hir::Attribute] { if let Some(did) = did.as_local() { - self.hir().attrs(self.local_def_id_to_hir_id(did)) + self.hir_attrs(self.local_def_id_to_hir_id(did)) } else { self.attrs_for_def(did) } @@ -1720,7 +1720,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> impl Iterator { let did: DefId = did.into(); if let Some(did) = did.as_local() { - self.hir().attrs(self.local_def_id_to_hir_id(did)).iter() + self.hir_attrs(self.local_def_id_to_hir_id(did)).iter() } else { self.attrs_for_def(did).iter() } @@ -1764,7 +1764,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> impl Iterator { let filter_fn = move |a: &&hir::Attribute| a.path_matches(attr); if let Some(did) = did.as_local() { - self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn) + self.hir_attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn) } else { self.attrs_for_def(did).iter().filter(filter_fn) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 6c62c04f42e4c..f1d03d0a6594b 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -50,7 +50,7 @@ impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id)); + let name = ty::tls::with(|tcx| tcx.hir_name(self.var_path.hir_id)); write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id) } } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 7d9c23c05f950..06054e22e7601 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -310,7 +310,7 @@ impl<'tcx> TypeckResults<'tcx> { pub fn node_type(&self, id: HirId) -> Ty<'tcx> { self.node_type_opt(id).unwrap_or_else(|| { - bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir().node_to_string(id))) + bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir_id_to_string(id))) }) } @@ -554,7 +554,7 @@ fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) { ty::tls::with(|tcx| { bug!( "node {} cannot be placed in TypeckResults with hir_owner {:?}", - tcx.hir().node_to_string(hir_id), + tcx.hir_id_to_string(hir_id), hir_owner ) }); diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index f9fa750e750b3..2909dea98b747 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -485,7 +485,7 @@ fn construct_fn<'tcx>( }; if let Some(custom_mir_attr) = - tcx.hir().attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir) + tcx.hir_attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir) { return custom::build_custom_mir( tcx, @@ -741,7 +741,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { coroutine: Option>>, ) -> Builder<'a, 'tcx> { let tcx = infcx.tcx; - let attrs = tcx.hir().attrs(hir_id); + let attrs = tcx.hir_attrs(hir_id); // Some functions always have overflow checks enabled, // however, they may not get codegen'd, depending on // the settings for the crate they are codegened in. diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 8156123949121..27ff01b48034b 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -942,14 +942,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert_eq!(orig_id.owner, self.hir_id.owner); let mut id = orig_id; - let hir = self.tcx.hir(); loop { if id == self.hir_id { // This is a moderately common case, mostly hit for previously unseen nodes. break; } - if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) { + if self.tcx.hir_attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) { // This is a rare case. It's for a node path that doesn't reach the root due to an // intervening lint level attribute. This result doesn't get cached. return id; diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index fa5db32d9134c..8e96d46dac272 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -8,7 +8,6 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // The `builder` module used to be named `build`, but that was causing GitHub's diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index e46e8c9871a5a..b8af77245f25d 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -1041,7 +1041,7 @@ impl<'tcx> ThirBuildCx<'tcx> { "Should have already errored about late bound consts: {def_id:?}" ); }; - let name = self.tcx.hir().name(hir_id); + let name = self.tcx.hir_name(hir_id); let param = ty::ParamConst::new(index, name); ExprKind::ConstParam { param, def_id } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 3d55c1401b637..b3daed8a7e017 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -73,7 +73,6 @@ struct ThirBuildCx<'tcx> { impl<'tcx> ThirBuildCx<'tcx> { fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { let typeck_results = tcx.typeck(def); - let hir = tcx.hir(); let hir_id = tcx.local_def_id_to_hir_id(def); let body_type = match tcx.hir_body_owner_kind(def) { @@ -111,8 +110,8 @@ impl<'tcx> ThirBuildCx<'tcx> { typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, body_owner: def.to_def_id(), - apply_adjustments: hir - .attrs(hir_id) + apply_adjustments: tcx + .hir_attrs(hir_id) .iter() .all(|attr| attr.name_or_empty() != rustc_span::sym::custom_mir), } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index dadd1e8546117..cbd29ba837ef6 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1043,7 +1043,7 @@ fn find_fallback_pattern_typo<'tcx>( for item in cx.tcx.hir_crate_items(()).free_items() { if let DefKind::Use = cx.tcx.def_kind(item.owner_id) { // Look for consts being re-exported. - let item = cx.tcx.hir().expect_item(item.owner_id.def_id); + let item = cx.tcx.hir_expect_item(item.owner_id.def_id); let use_name = item.ident.name; let hir::ItemKind::Use(path, _) = item.kind else { continue; diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index a8a56baa1ffc0..a0efc623b8e7e 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -7,7 +7,6 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::ty; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 8aa14d15644b0..739cee5d7f4c9 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -12,7 +12,6 @@ #![feature(never_type)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use hir::ConstContext; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 714b64b3a231c..8f6914f3d7242 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -4,7 +4,6 @@ #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(let_chains)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_hir::lang_items::LangItem; diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index d67ae2550d967..f6963a790675f 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -6,7 +6,6 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_type_ir_inherent)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod canonicalizer; diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 1a104ff5e3375..2edc8c83017d8 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -12,7 +12,6 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(string_from_utf8_lossy_owned)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index e05cc6d29d84f..5b8a2fe52d3f5 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -13,7 +13,6 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))) )] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub use Alignment::*; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c6ae2c0fb9bfd..ece5a53aaa9c4 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -52,7 +52,7 @@ fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) hir::ImplItemKind::Const(..) => Target::AssocConst, hir::ImplItemKind::Fn(..) => { let parent_def_id = tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let containing_item = tcx.hir().expect_item(parent_def_id); + let containing_item = tcx.hir_expect_item(parent_def_id); let containing_impl_is_for_trait = match &containing_item.kind { hir::ItemKind::Impl(impl_) => impl_.of_trait.is_some(), _ => bug!("parent of an ImplItem must be an Impl"), @@ -114,7 +114,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut doc_aliases = FxHashMap::default(); let mut specified_inline = None; let mut seen = FxHashMap::default(); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { match attr { Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { @@ -899,7 +899,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Some(location) = match target { Target::AssocTy => { let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id; - let containing_item = self.tcx.hir().expect_item(parent_def_id); + let containing_item = self.tcx.hir_expect_item(parent_def_id); if Target::from_item(containing_item) == Target::Impl { Some("type alias in implementation block") } else { @@ -908,7 +908,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Target::AssocConst => { let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id; - let containing_item = self.tcx.hir().expect_item(parent_def_id); + let containing_item = self.tcx.hir_expect_item(parent_def_id); // We can't link to trait impl's consts. let err = "associated constant in trait implementation block"; match containing_item.kind { @@ -952,7 +952,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { tcx.dcx().emit_err(errors::DocAliasBadLocation { span, attr_str, location }); return; } - let item_name = self.tcx.hir().name(hir_id); + let item_name = self.tcx.hir_name(hir_id); if item_name == doc_alias { tcx.dcx().emit_err(errors::DocAliasNotAnAlias { span, attr_str }); return; @@ -1481,7 +1481,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // `#[must_use]` can be applied to a trait method definition with a default body if let Target::Method(MethodKind::Trait { body: true }) = target && let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id - && let containing_item = self.tcx.hir().expect_item(parent_def_id) + && let containing_item = self.tcx.hir_expect_item(parent_def_id) && let hir::ItemKind::Trait(..) = containing_item.kind { return; @@ -2572,7 +2572,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match (target, force_inline_attr) { (Target::Closure, None) => { let is_coro = matches!( - self.tcx.hir().expect_expr(hir_id).kind, + self.tcx.hir_expect_expr(hir_id).kind, hir::ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Coroutine(..) | hir::ClosureKind::CoroutineClosure(..), @@ -2644,8 +2644,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr]; let spans = self .tcx - .hir() - .attrs(where_predicate.hir_id) + .hir_attrs(where_predicate.hir_id) .iter() .filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym))) .map(|attr| attr.span()) @@ -2814,7 +2813,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { } fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) { - let attrs = tcx.hir().attrs(item.hir_id()); + let attrs = tcx.hir_attrs(item.hir_id()); for attr in attrs { if attr.has_name(sym::inline) { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 7a14a7a5db299..7029c60c3439b 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -361,7 +361,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { self.tcx.hir_fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id)) && matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None) && let TyKind::Path(hir::QPath::Resolved(_, path)) = - self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind + self.tcx.hir_expect_item(local_impl_of).expect_impl().self_ty.kind && let Res::Def(def_kind, did) = path.res { match def_kind { @@ -424,7 +424,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { for impl_def_id in self.tcx.all_impls(item.owner_id.to_def_id()) { if let Some(local_def_id) = impl_def_id.as_local() && let ItemKind::Impl(impl_ref) = - self.tcx.hir().expect_item(local_def_id).kind + self.tcx.hir_expect_item(local_def_id).kind { // skip items // mark dependent traits live @@ -448,7 +448,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { for impl_id in self.tcx.all_impls(trait_id) { if let Some(local_impl_id) = impl_id.as_local() && let ItemKind::Impl(impl_ref) = - self.tcx.hir().expect_item(local_impl_id).kind + self.tcx.hir_expect_item(local_impl_id).kind { if !matches!(trait_item.kind, hir::TraitItemKind::Type(..)) && !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty) diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 323b414cca04c..e13d94c1031ac 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -19,7 +19,7 @@ use rustc_span::{Symbol, sym}; use crate::errors::DuplicateDiagnosticItemInCrate; fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) { - let attrs = tcx.hir().attrs(owner.into()); + let attrs = tcx.hir_attrs(owner.into()); if let Some(name) = extract(attrs) { // insert into our table collect_item(tcx, diagnostic_items, name, owner.to_def_id()); diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 25e679a84601e..d2729876ebbb4 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -31,7 +31,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { } // If the user wants no main function at all, then stop here. - if attr::contains_name(tcx.hir().attrs(CRATE_HIR_ID), sym::no_main) { + if attr::contains_name(tcx.hir_attrs(CRATE_HIR_ID), sym::no_main) { return None; } @@ -45,7 +45,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { } fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Option { - let attrs = ctxt.tcx.hir().attrs(id.hir_id()); + let attrs = ctxt.tcx.hir_attrs(id.hir_id()); attr::find_by_name(attrs, sym).map(|attr| attr.span()) } @@ -61,7 +61,7 @@ fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) { let at_root = ctxt.tcx.opt_local_parent(id.owner_id.def_id) == Some(CRATE_DEF_ID); - let attrs = ctxt.tcx.hir().attrs(id.hir_id()); + let attrs = ctxt.tcx.hir_attrs(id.hir_id()); let entry_point_type = rustc_ast::entry::entry_point_type( attrs, at_root, diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 509c2f5477524..84b92d49f24c2 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -60,19 +60,18 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> { .expect("owning item has no entry"); if max != self.hir_ids_seen.len() - 1 { - let hir = self.tcx.hir(); let pretty_owner = self.tcx.hir_def_path(owner.def_id).to_string_no_crate_verbose(); let missing_items: Vec<_> = (0..=max as u32) .map(|i| ItemLocalId::from_u32(i)) .filter(|&local_id| !self.hir_ids_seen.contains(local_id)) - .map(|local_id| hir.node_to_string(HirId { owner, local_id })) + .map(|local_id| self.tcx.hir_id_to_string(HirId { owner, local_id })) .collect(); let seen_items: Vec<_> = self .hir_ids_seen .iter() - .map(|local_id| hir.node_to_string(HirId { owner, local_id })) + .map(|local_id| self.tcx.hir_id_to_string(HirId { owner, local_id })) .collect(); self.error(|| { @@ -137,7 +136,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> { self.error(|| { format!( "HirIdValidator: The recorded owner of {} is {} instead of {}", - self.tcx.hir().node_to_string(hir_id), + self.tcx.hir_id_to_string(hir_id), self.tcx.hir_def_path(hir_id.owner.def_id).to_string_no_crate_verbose(), self.tcx.hir_def_path(owner.def_id).to_string_no_crate_verbose() ) diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 1aa077ad2bb57..93ff0f66d695b 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -12,7 +12,6 @@ #![feature(map_try_insert)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 822804893fe2a..ed70d9ee91f5a 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -157,7 +157,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { if let Some(upvars) = tcx.upvars_mentioned(def_id) { for &var_hir_id in upvars.keys() { - let var_name = tcx.hir().name(var_hir_id); + let var_name = tcx.hir_name(var_hir_id); maps.add_variable(Upvar(var_hir_id, var_name)); } } diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 8e59c0b3251ca..b06f16cc7bd2f 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -222,7 +222,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { if let Some(break_expr) = opt_expr { let (head, loop_label, loop_kind) = if let Some(loop_id) = loop_id { - match self.tcx.hir().expect_expr(loop_id).kind { + match self.tcx.hir_expect_expr(loop_id).kind { hir::ExprKind::Loop(_, label, source, sp) => { (Some(sp), label, Some(source)) } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index fd465717bf766..599a08bac20de 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -291,7 +291,7 @@ impl<'tcx> ReachableContext<'tcx> { _ => { bug!( "found unexpected node kind in worklist: {} ({:?})", - self.tcx.hir().node_to_string(self.tcx.local_def_id_to_hir_id(search_item)), + self.tcx.hir_id_to_string(self.tcx.local_def_id_to_hir_id(search_item)), node, ); } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 0fcf6a80ec4de..aea4386295f31 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -118,7 +118,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { ) where F: FnOnce(&mut Self), { - let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); + let attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id)); debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs); let depr = attr::find_attr!(attrs, AttributeKind::Deprecation{deprecation, span} => (*deprecation, *span)); @@ -795,7 +795,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { }) => { let features = self.tcx.features(); if features.staged_api() { - let attrs = self.tcx.hir().attrs(item.hir_id()); + let attrs = self.tcx.hir_attrs(item.hir_id()); let stab = attr::find_attr!(attrs, AttributeKind::Stability{stability, span} => (*stability, *span)); // FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem @@ -1034,7 +1034,7 @@ fn is_unstable_reexport(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { } // If this is a path that isn't a use, we don't need to do anything special - if !matches!(tcx.hir().expect_item(def_id).kind, ItemKind::Use(..)) { + if !matches!(tcx.hir_expect_item(def_id).kind, ItemKind::Use(..)) { return false; } diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index a3400ebb79937..eeea724a29b45 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -6,7 +6,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(feature = "rustc", feature(let_chains))] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod constructor; diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs index 365bc2d863f47..8980b644f59b1 100644 --- a/compiler/rustc_pattern_analysis/tests/common/mod.rs +++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs @@ -5,7 +5,7 @@ use rustc_pattern_analysis::usefulness::{PlaceValidity, UsefulnessReport}; use rustc_pattern_analysis::{MatchArm, PatCx, PrivateUninhabitedField}; /// Sets up `tracing` for easier debugging. Tries to look like the `rustc` setup. -pub fn init_tracing() { +fn init_tracing() { use tracing_subscriber::Layer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; @@ -24,7 +24,7 @@ pub fn init_tracing() { /// A simple set of types. #[allow(dead_code)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum Ty { +pub(super) enum Ty { /// Booleans Bool, /// 8-bit unsigned integers @@ -41,7 +41,7 @@ pub enum Ty { /// The important logic. impl Ty { - pub fn sub_tys(&self, ctor: &Constructor) -> Vec { + pub(super) fn sub_tys(&self, ctor: &Constructor) -> Vec { use Constructor::*; match (ctor, *self) { (Struct, Ty::Tuple(tys)) => tys.iter().copied().collect(), @@ -63,7 +63,7 @@ impl Ty { } } - pub fn ctor_set(&self) -> ConstructorSet { + fn ctor_set(&self) -> ConstructorSet { match *self { Ty::Bool => ConstructorSet::Bool, Ty::U8 => ConstructorSet::Integers { @@ -104,7 +104,7 @@ impl Ty { } } - pub fn write_variant_name( + fn write_variant_name( &self, f: &mut std::fmt::Formatter<'_>, ctor: &Constructor, @@ -120,7 +120,7 @@ impl Ty { } /// Compute usefulness in our simple context (and set up tracing for easier debugging). -pub fn compute_match_usefulness<'p>( +pub(super) fn compute_match_usefulness<'p>( arms: &[MatchArm<'p, Cx>], ty: Ty, scrut_validity: PlaceValidity, @@ -137,7 +137,7 @@ pub fn compute_match_usefulness<'p>( } #[derive(Debug)] -pub struct Cx; +pub(super) struct Cx; /// The context for pattern analysis. Forwards anything interesting to `Ty` methods. impl PatCx for Cx { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index ff203b2938e06..f45e8c065b3c1 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -6,7 +6,6 @@ #![feature(let_chains)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod errors; @@ -493,7 +492,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { ) { // Non-opaque macros cannot make other items more accessible than they already are. let hir_id = self.tcx.local_def_id_to_hir_id(local_def_id); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); if attr::find_attr!(attrs, AttributeKind::MacroTransparency(x) => *x) .unwrap_or(Transparency::fallback(md.macro_rules)) @@ -573,7 +572,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { // have normal hygiene, so we can treat them like other items without type // privacy and mark them reachable. DefKind::Macro(_) => { - let item = self.tcx.hir().expect_item(def_id); + let item = self.tcx.hir_expect_item(def_id); if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind { if vis.is_accessible_from(module, self.tcx) { self.update(def_id, macro_ev, Level::Reachable); @@ -597,7 +596,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { DefKind::Struct | DefKind::Union => { // While structs and unions have type privacy, their fields do not. - let item = self.tcx.hir().expect_item(def_id); + let item = self.tcx.hir_expect_item(def_id); if let hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) = item.kind { diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 73c205fdb17d1..40da46a027dfe 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -8,7 +8,6 @@ #![feature(min_specialization)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_data_structures::stable_hasher::HashStable; diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index ee984095ad84b..a546362414cf4 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -6,7 +6,6 @@ #![feature(hash_raw_entry)] #![feature(let_chains)] #![feature(min_specialization)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod cache; diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 9f062b3935fd9..817aa5b43852b 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -153,9 +153,13 @@ resolve_extern_crate_self_requires_renaming = `extern crate self;` requires renaming .suggestion = rename the `self` crate to be able to import it +resolve_forward_declared_generic_in_const_param_ty = + const parameter types cannot reference parameters before they are declared + .label = const parameter type cannot reference `{$param}` before it is declared + resolve_forward_declared_generic_param = - generic parameters with a default cannot use forward declared identifiers - .label = defaulted generic parameters cannot be forward declared + generic parameter defaults cannot reference parameters before they are declared + .label = cannot reference `{$param}` before it is declared resolve_found_an_item_configured_out = found an item that was configured out @@ -377,9 +381,11 @@ resolve_self_imports_only_allowed_within_multipart_suggestion = resolve_self_imports_only_allowed_within_suggestion = consider importing the module directly +resolve_self_in_const_generic_ty = + cannot use `Self` in const parameter type + resolve_self_in_generic_param_default = generic parameters cannot use `Self` in their defaults - .label = `Self` in generic parameter default resolve_similarly_named_defined_here = similarly named {$candidate_descr} `{$candidate}` defined here diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 88d1126de1aea..41f4254eede44 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -42,10 +42,10 @@ use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; use crate::{ AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize, - HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, ModuleKind, - ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, - ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError, - errors as errs, path_names_to_string, + ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, + ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, + PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, + VisResolutionError, errors as errs, path_names_to_string, }; type Res = def::Res; @@ -887,9 +887,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { participle, name, }), - ResolutionError::ForwardDeclaredGenericParam => { - self.dcx().create_err(errs::ForwardDeclaredGenericParam { span }) - } + ResolutionError::ForwardDeclaredGenericParam(param, reason) => match reason { + ForwardGenericParamBanReason::Default => { + self.dcx().create_err(errs::ForwardDeclaredGenericParam { param, span }) + } + ForwardGenericParamBanReason::ConstParamTy => self + .dcx() + .create_err(errs::ForwardDeclaredGenericInConstParamTy { param, span }), + }, ResolutionError::ParamInTyOfConstParam { name } => { self.dcx().create_err(errs::ParamInTyOfConstParam { span, name }) } @@ -908,9 +913,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self .dcx() .create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }), - ResolutionError::SelfInGenericParamDefault => { - self.dcx().create_err(errs::SelfInGenericParamDefault { span }) - } + ResolutionError::ForwardDeclaredSelf(reason) => match reason { + ForwardGenericParamBanReason::Default => { + self.dcx().create_err(errs::SelfInGenericParamDefault { span }) + } + ForwardGenericParamBanReason::ConstParamTy => { + self.dcx().create_err(errs::SelfInConstGenericTy { span }) + } + }, ResolutionError::UnreachableLabel { name, definition_span, suggestion } => { let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) = match suggestion { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index b5d3e5ea77672..2ae6892bc93e6 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -338,6 +338,16 @@ pub(crate) struct ForwardDeclaredGenericParam { #[primary_span] #[label] pub(crate) span: Span, + pub(crate) param: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_forward_declared_generic_in_const_param_ty)] +pub(crate) struct ForwardDeclaredGenericInConstParamTy { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) param: Symbol, } #[derive(Diagnostic)] @@ -353,7 +363,13 @@ pub(crate) struct ParamInTyOfConstParam { #[diag(resolve_self_in_generic_param_default, code = E0735)] pub(crate) struct SelfInGenericParamDefault { #[primary_span] - #[label] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_self_in_const_generic_ty)] +pub(crate) struct SelfInConstGenericTy { + #[primary_span] pub(crate) span: Span, } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index d9776be4dd0a6..5f0a2a597e9b4 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1117,13 +1117,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { debug!("validate_res_from_ribs({:?})", res); let ribs = &all_ribs[rib_index + 1..]; - // An invalid forward use of a generic parameter from a previous default. - if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind { + // An invalid forward use of a generic parameter from a previous default + // or in a const param ty. + if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind { if let Some(span) = finalize { let res_error = if rib_ident.name == kw::SelfUpper { - ResolutionError::SelfInGenericParamDefault + ResolutionError::ForwardDeclaredSelf(reason) } else { - ResolutionError::ForwardDeclaredGenericParam + ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason) }; self.report_error(span, res_error); } @@ -1131,17 +1132,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return Res::Err; } - if let RibKind::ConstParamTy = all_ribs[rib_index].kind { - if let Some(span) = finalize { - self.report_error( - span, - ResolutionError::ParamInTyOfConstParam { name: rib_ident.name }, - ); - } - assert_eq!(res, Res::Err); - return Res::Err; - } - match res { Res::Local(_) => { use ResolutionError::*; @@ -1153,7 +1143,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | RibKind::FnOrCoroutine | RibKind::Module(..) | RibKind::MacroDefinition(..) - | RibKind::ForwardGenericParamBan => { + | RibKind::ForwardGenericParamBan(_) => { // Nothing to do. Continue. } RibKind::Item(..) | RibKind::AssocItem => { @@ -1247,12 +1237,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | RibKind::MacroDefinition(..) | RibKind::InlineAsmSym | RibKind::AssocItem - | RibKind::ConstParamTy - | RibKind::ForwardGenericParamBan => { + | RibKind::ForwardGenericParamBan(_) => { // Nothing to do. Continue. continue; } + RibKind::ConstParamTy => { + if !self.tcx.features().generic_const_parameter_types() { + if let Some(span) = finalize { + self.report_error( + span, + ResolutionError::ParamInTyOfConstParam { + name: rib_ident.name, + }, + ); + } + return Res::Err; + } else { + continue; + } + } + RibKind::ConstantItem(trivial, _) => { if let ConstantHasGenerics::No(cause) = trivial { // HACK(min_const_generics): If we encounter `Self` in an anonymous @@ -1325,8 +1330,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | RibKind::MacroDefinition(..) | RibKind::InlineAsmSym | RibKind::AssocItem - | RibKind::ConstParamTy - | RibKind::ForwardGenericParamBan => continue, + | RibKind::ForwardGenericParamBan(_) => continue, + + RibKind::ConstParamTy => { + if !self.tcx.features().generic_const_parameter_types() { + if let Some(span) = finalize { + self.report_error( + span, + ResolutionError::ParamInTyOfConstParam { + name: rib_ident.name, + }, + ); + } + return Res::Err; + } else { + continue; + } + } RibKind::ConstantItem(trivial, _) => { if let ConstantHasGenerics::No(cause) = trivial { @@ -1377,6 +1397,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } _ => {} } + res } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2c3e4bb505cc7..d28988cd74f10 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -207,7 +207,7 @@ pub(crate) enum RibKind<'ra> { /// All bindings in this rib are generic parameters that can't be used /// from the default of a generic parameter because they're not declared /// before said generic parameter. Also see the `visit_generics` override. - ForwardGenericParamBan, + ForwardGenericParamBan(ForwardGenericParamBanReason), /// We are inside of the type of a const parameter. Can't refer to any /// parameters. @@ -218,6 +218,12 @@ pub(crate) enum RibKind<'ra> { InlineAsmSym, } +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub(crate) enum ForwardGenericParamBanReason { + Default, + ConstParamTy, +} + impl RibKind<'_> { /// Whether this rib kind contains generic parameters, as opposed to local /// variables. @@ -232,7 +238,7 @@ impl RibKind<'_> { RibKind::ConstParamTy | RibKind::AssocItem | RibKind::Item(..) - | RibKind::ForwardGenericParamBan => true, + | RibKind::ForwardGenericParamBan(_) => true, } } @@ -246,7 +252,7 @@ impl RibKind<'_> { | RibKind::Item(..) | RibKind::ConstantItem(..) | RibKind::Module(..) - | RibKind::ForwardGenericParamBan + | RibKind::ForwardGenericParamBan(_) | RibKind::ConstParamTy | RibKind::InlineAsmSym => true, } @@ -1561,8 +1567,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // provide previous type parameters as they're built. We // put all the parameters on the ban list and then remove // them one by one as they are processed and become available. - let mut forward_ty_ban_rib = Rib::new(RibKind::ForwardGenericParamBan); - let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan); + let mut forward_ty_ban_rib = + Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default)); + let mut forward_const_ban_rib = + Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default)); for param in params.iter() { match param.kind { GenericParamKind::Type { .. } => { @@ -1593,16 +1601,24 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err); } + // NOTE: We use different ribs here not for a technical reason, but just + // for better diagnostics. let mut forward_ty_ban_rib_const_param_ty = Rib { bindings: forward_ty_ban_rib.bindings.clone(), patterns_with_skipped_bindings: FxHashMap::default(), - kind: RibKind::ConstParamTy, + kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy), }; let mut forward_const_ban_rib_const_param_ty = Rib { bindings: forward_const_ban_rib.bindings.clone(), patterns_with_skipped_bindings: FxHashMap::default(), - kind: RibKind::ConstParamTy, + kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy), }; + // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better + // diagnostics, so we don't mention anything about const param tys having generics at all. + if !self.r.tcx.features().generic_const_parameter_types() { + forward_ty_ban_rib_const_param_ty.bindings.clear(); + forward_const_ban_rib_const_param_ty.bindings.clear(); + } self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { for param in params { @@ -1628,9 +1644,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Allow all following defaults to refer to this type parameter. let i = &Ident::with_dummy_span(param.ident.name); forward_ty_ban_rib.bindings.remove(i); - if this.r.tcx.features().generic_const_parameter_types() { - forward_ty_ban_rib_const_param_ty.bindings.remove(i); - } + forward_ty_ban_rib_const_param_ty.bindings.remove(i); } GenericParamKind::Const { ref ty, kw_span: _, ref default } => { // Const parameters can't have param bounds. @@ -1641,9 +1655,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if this.r.tcx.features().generic_const_parameter_types() { this.visit_ty(ty) } else { + this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy)); + this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy)); this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| { this.visit_ty(ty) }); + this.ribs[TypeNS].pop().unwrap(); + this.ribs[ValueNS].pop().unwrap(); } forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap(); forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap(); @@ -1662,9 +1680,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Allow all following defaults to refer to this const parameter. let i = &Ident::with_dummy_span(param.ident.name); forward_const_ban_rib.bindings.remove(i); - if this.r.tcx.features().generic_const_parameter_types() { - forward_const_ban_rib_const_param_ty.bindings.remove(i); - } + forward_const_ban_rib_const_param_ty.bindings.remove(i); } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ccdca8552320f..495ce843fcd22 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -20,7 +20,6 @@ #![feature(let_chains)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::{Cell, RefCell}; @@ -32,7 +31,10 @@ use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; use effective_visibilities::EffectiveVisibilitiesVisitor; use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; use imports::{Import, ImportData, ImportKind, NameResolution}; -use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification}; +use late::{ + ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource, + UnnecessaryQualification, +}; use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::expand::StrippedCfgItem; @@ -273,7 +275,7 @@ enum ResolutionError<'ra> { shadowed_binding_span: Span, }, /// Error E0128: generic parameters with a default cannot use forward-declared identifiers. - ForwardDeclaredGenericParam, + ForwardDeclaredGenericParam(Symbol, ForwardGenericParamBanReason), // FIXME(generic_const_parameter_types): This should give custom output specifying it's only // problematic to use *forward declared* parameters when the feature is enabled. /// ERROR E0770: the type of const parameters must not depend on other generic parameters. @@ -287,7 +289,7 @@ enum ResolutionError<'ra> { /// This error is emitted even with `generic_const_exprs`. ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant }, /// Error E0735: generic parameters with a default cannot use `Self` - SelfInGenericParamDefault, + ForwardDeclaredSelf(ForwardGenericParamBanReason), /// Error E0767: use of unreachable label UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option }, /// Error E0323, E0324, E0325: mismatch between trait item and impl item. diff --git a/compiler/rustc_sanitizers/src/lib.rs b/compiler/rustc_sanitizers/src/lib.rs index 55be931bcd6d4..e4792563e71ea 100644 --- a/compiler/rustc_sanitizers/src/lib.rs +++ b/compiler/rustc_sanitizers/src/lib.rs @@ -5,7 +5,6 @@ // tidy-alphabetical-start #![feature(let_chains)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod cfi; diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 9e9b78cfdd57c..13c1a273eb816 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -14,7 +14,6 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub use self::serialize::{Decodable, Decoder, Encodable, Encoder}; diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index d432e84fdb224..0e19b982a133e 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -7,7 +7,6 @@ // To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums // with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers"). #![recursion_limit = "256"] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod errors; diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 2215e2f01ade0..9f88887530614 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -15,7 +15,6 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod rustc_internal; diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index acd3b75835105..aa1921fc8e784 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -272,7 +272,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let did = tables[def_id]; let attrs_iter = if let Some(did) = did.as_local() { - tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter() + tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)).iter() } else { tcx.attrs_for_def(did).iter() }; diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 798e186a94b1a..f19d4d9f3624e 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -32,7 +32,6 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(slice_as_chunks)] -#![warn(unreachable_pub)] // tidy-alphabetical-end // The code produced by the `Encodable`/`Decodable` derive macros refer to diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 4312c82815c16..269401ef3a2de 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -93,7 +93,6 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_hir::def::DefKind; diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 7ebe96960ed0f..a8d7da5692de4 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -16,7 +16,6 @@ #![feature(let_chains)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 42d37418fb848..baf2489b2b8b2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -509,7 +509,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { hir::MatchSource::TryDesugar(scrut_hir_id), ) => { if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { - let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); + let scrut_expr = self.tcx.hir_expect_expr(scrut_hir_id); let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); self.typeck_results @@ -548,7 +548,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) => match source { hir::MatchSource::TryDesugar(scrut_hir_id) => { if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { - let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); + let scrut_expr = self.tcx.hir_expect_expr(scrut_hir_id); let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); self.typeck_results diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index a6d8eb6add7d0..40958ec1088bc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -1351,7 +1351,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { && !has_impl_trait(def_id) // FIXME(fn_delegation): In delegation item argument spans are equal to last path // segment. This leads to ICE's when emitting `multipart_suggestion`. - && tcx.hir().opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none() + && tcx.hir_opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none() { let successor = method_args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo())); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 51b2a0b36bb91..5583deda99a49 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -743,7 +743,7 @@ fn foo(&self) -> Self::T { String::new() } if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() { let opaque_local_def_id = def_id.as_local(); let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id { - tcx.hir().expect_opaque_ty(opaque_local_def_id) + tcx.hir_expect_opaque_ty(opaque_local_def_id) } else { return false; }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index fecb38ab597e4..c7f0a88f951a8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -1023,7 +1023,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { format!(" for lifetime parameter `{name}`") } infer::UpvarRegion(ref upvar_id, _) => { - let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); + let var_name = self.tcx.hir_name(upvar_id.var_path.hir_id); format!(" for capture of `{var_name}` by closure") } infer::Nll(..) => bug!("NLL variable found in lexical phase"), diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index a7e68e6419d84..cdbb92f4c7baa 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -778,8 +778,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let exp_local_id = exp_def_id.as_local()?; match ( - &self.tcx.hir().expect_opaque_ty(last_local_id), - &self.tcx.hir().expect_opaque_ty(exp_local_id), + &self.tcx.hir_expect_opaque_ty(last_local_id), + &self.tcx.hir_expect_opaque_ty(exp_local_id), ) { ( hir::OpaqueTy { bounds: last_bounds, .. }, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ad46a15a5ac6d..4f89f3c2b4992 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -22,7 +22,6 @@ use rustc_hir::{ expr_needs_parens, is_range_literal, }; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk}; -use rustc_middle::hir::map; use rustc_middle::traits::IsConstable; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::{ @@ -93,7 +92,7 @@ impl<'a, 'tcx> CoroutineData<'a, 'tcx> { fn get_from_await_ty( &self, visitor: AwaitsVisitor, - hir: map::Map<'tcx>, + tcx: TyCtxt<'tcx>, ty_matches: F, ) -> Option where @@ -102,7 +101,7 @@ impl<'a, 'tcx> CoroutineData<'a, 'tcx> { visitor .awaits .into_iter() - .map(|id| hir.expect_expr(id)) + .map(|id| tcx.hir_expect_expr(id)) .find(|await_expr| ty_matches(ty::Binder::dummy(self.0.expr_ty_adjusted(await_expr)))) .map(|expr| expr.span) } @@ -2180,8 +2179,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: &mut Diag<'_, G>, obligation: &PredicateObligation<'tcx>, ) -> bool { - let hir = self.tcx.hir(); - // Attempt to detect an async-await error by looking at the obligation causes, looking // for a coroutine to be present. // @@ -2350,7 +2347,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut interior_or_upvar_span = None; - let from_awaited_ty = coroutine_data.get_from_await_ty(visitor, hir, ty_matches); + let from_awaited_ty = coroutine_data.get_from_await_ty(visitor, self.tcx, ty_matches); debug!(?from_awaited_ty); // Avoid disclosing internal information to downstream crates. @@ -2428,7 +2425,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Special case the primary error message when send or sync is the trait that was // not implemented. - let hir = self.tcx.hir(); let trait_explanation = if let Some(name @ (sym::Send | sym::Sync)) = self.tcx.get_diagnostic_name(trait_pred.def_id()) { @@ -2455,7 +2451,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .parent(coroutine_did) .as_local() .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id)) .map(|name| { format!("future returned by `{name}` is not {trait_name}") })?, @@ -2479,7 +2475,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .parent(coroutine_did) .as_local() .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id)) .map(|name| { format!("async iterator returned by `{name}` is not {trait_name}") })?, @@ -2502,7 +2498,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .parent(coroutine_did) .as_local() .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id)) .map(|name| { format!("iterator returned by `{name}` is not {trait_name}") })? @@ -3569,7 +3565,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ObligationCauseCode::OpaqueReturnType(expr_info) => { let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info { let expr_ty = tcx.short_string(expr_ty, err.long_ty_path()); - let expr = tcx.hir().expect_expr(hir_id); + let expr = tcx.hir_expect_expr(hir_id); (expr_ty, expr) } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id() && let body = tcx.hir_body(body_id) diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index b235d0da83cca..b18fb0fb8fd31 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -31,7 +31,6 @@ #![feature(unwrap_infallible)] #![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc -#![warn(unreachable_pub)] // For rustdoc // tidy-alphabetical-end pub mod error_reporting; diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index cc329ca33288c..4a889abfc28f1 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -70,7 +70,7 @@ pub(crate) fn codegen_select_candidate<'tcx>( infcx.err_ctxt().report_overflow_obligation_cycle(&cycle); } } - return Err(CodegenObligationError::FulfillmentError); + return Err(CodegenObligationError::Unimplemented); } let impl_source = infcx.resolve_vars_if_possible(impl_source); diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index d2f979bd6d9dc..697c839180312 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -2,7 +2,6 @@ // tidy-alphabetical-start #![recursion_limit = "256"] -#![warn(unreachable_pub)] // tidy-alphabetical-end mod codegen; diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 81a11f7cfb267..00928137d2976 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![feature(never_type)] -#![warn(unreachable_pub)] // tidy-alphabetical-end pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set}; diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index c84055f5b84fe..b7684e85d4128 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -21,7 +21,7 @@ pub(crate) fn provide(providers: &mut Providers) { } fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); match item.kind { hir::ItemKind::Trait(.., trait_item_refs) => { // We collect RPITITs for each trait method's return type and create a @@ -96,7 +96,7 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem { let id = tcx.local_def_id_to_hir_id(def_id); let parent_def_id = tcx.hir_get_parent_item(id); - let parent_item = tcx.hir().expect_item(parent_def_id.def_id); + let parent_item = tcx.hir_expect_item(parent_def_id.def_id); match parent_item.kind { hir::ItemKind::Impl(impl_) => { if let Some(impl_item_ref) = impl_.items.iter().find(|i| i.id.owner_id.def_id == def_id) @@ -201,7 +201,7 @@ fn associated_types_for_impl_traits_in_associated_fn( let mut visitor = RPITVisitor { rpits: FxIndexSet::default() }; - if let Some(output) = tcx.hir().get_fn_output(fn_def_id) { + if let Some(output) = tcx.hir_get_fn_output(fn_def_id) { visitor.visit_fn_ret_ty(output); tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 6205578bf7476..aeaa83c77b5f1 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -161,7 +161,7 @@ fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator, def_id: LocalDefId) -> impl Iterator { - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); if let hir::ItemKind::Impl(impl_) = item.kind { let trait_args = impl_ .of_trait diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 6dc5a9c4a4798..90b3517eded88 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -107,11 +107,9 @@ fn resolve_associated_item<'tcx>( let input = typing_env.as_query_input(trait_ref); let vtbl = match tcx.codegen_select_candidate(input) { Ok(vtbl) => vtbl, - Err( - CodegenObligationError::Ambiguity - | CodegenObligationError::Unimplemented - | CodegenObligationError::FulfillmentError, - ) => return Ok(None), + Err(CodegenObligationError::Ambiguity | CodegenObligationError::Unimplemented) => { + return Ok(None); + } Err(CodegenObligationError::UnconstrainedParam(guar)) => return Err(guar), }; diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 8be1611bb9ac2..35cc6f3985652 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -16,7 +16,6 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(rustdoc_internals)] -#![warn(unreachable_pub)] // tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index a107925fb1885..3aad97d86cca1 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -187,7 +187,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { if !hir_id.is_owner() { return; } - let Some(defines) = self.tcx.hir_attrs(hir_id.owner).define_opaque else { + let Some(defines) = self.tcx.hir_attr_map(hir_id.owner).define_opaque else { return; }; for &(span, define) in defines { diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 15ef4e7d6c1d2..e2dfd9173fab8 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -6,7 +6,6 @@ feature(associated_type_defaults, never_type, rustc_attrs, negative_impls) )] #![cfg_attr(feature = "nightly", allow(internal_features))] -#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_type_ir; diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 5aa048c4cbc85..8472f90305007 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -373,8 +373,8 @@ pub enum ErrorKind { TooManyLinks, /// A filename was invalid. /// - /// This error can also cause if it exceeded the filename length limit. - #[unstable(feature = "io_error_more", issue = "86442")] + /// This error can also occur if a length limit for a name was exceeded. + #[stable(feature = "io_error_invalid_filename", since = "CURRENT_RUSTC_VERSION")] InvalidFilename, /// Program argument list too long. /// diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 12dd40d14e9bf..62d23c4ae6b23 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -1045,8 +1045,11 @@ impl Builder<'_> { // so this line allows the use of custom libcs. cargo.env("LIBC_CHECK_CFG", "1"); + let mut lint_flags = Vec::new(); + + // Lints for all in-tree code: compiler, rustdoc, cranelift, gcc, + // clippy, rustfmt, rust-analyzer, etc. if source_type == SourceType::InTree { - let mut lint_flags = Vec::new(); // When extending this list, add the new lints to the RUSTFLAGS of the // build_bootstrap function of src/bootstrap/bootstrap.py as well as // some code doesn't go through this `rustc` wrapper. @@ -1058,27 +1061,32 @@ impl Builder<'_> { rustdocflags.arg("-Dwarnings"); } - // This does not use RUSTFLAGS due to caching issues with Cargo. - // Clippy is treated as an "in tree" tool, but shares the same - // cache as other "submodule" tools. With these options set in - // RUSTFLAGS, that causes *every* shared dependency to be rebuilt. - // By injecting this into the rustc wrapper, this circumvents - // Cargo's fingerprint detection. This is fine because lint flags - // are always ignored in dependencies. Eventually this should be - // fixed via better support from Cargo. - cargo.env("RUSTC_LINT_FLAGS", lint_flags.join(" ")); - rustdocflags.arg("-Wrustdoc::invalid_codeblock_attributes"); } + // Lints just for `compiler/` crates. if mode == Mode::Rustc { - rustflags.arg("-Wrustc::internal"); - rustflags.arg("-Drustc::symbol_intern_string_literal"); + lint_flags.push("-Wrustc::internal"); + lint_flags.push("-Drustc::symbol_intern_string_literal"); // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all // of the individual lints are satisfied. - rustflags.arg("-Wkeyword_idents_2024"); - rustflags.arg("-Wunsafe_op_in_unsafe_fn"); - } + lint_flags.push("-Wkeyword_idents_2024"); + lint_flags.push("-Wunreachable_pub"); + lint_flags.push("-Wunsafe_op_in_unsafe_fn"); + } + + // This does not use RUSTFLAGS for two reasons. + // - Due to caching issues with Cargo. Clippy is treated as an "in + // tree" tool, but shares the same cache as other "submodule" tools. + // With these options set in RUSTFLAGS, that causes *every* shared + // dependency to be rebuilt. By injecting this into the rustc + // wrapper, this circumvents Cargo's fingerprint detection. This is + // fine because lint flags are always ignored in dependencies. + // Eventually this should be fixed via better support from Cargo. + // - RUSTFLAGS is ignored for proc macro crates that are being built on + // the host (because `--target` is given). But we want the lint flags + // to be applied to proc macro crates. + cargo.env("RUSTC_LINT_FLAGS", lint_flags.join(" ")); if self.config.rust_frame_pointers { rustflags.arg("-Cforce-frame-pointers=true"); diff --git a/src/doc/rustc-dev-guide/src/hir.md b/src/doc/rustc-dev-guide/src/hir.md index 51893d537d750..75f5a9e204528 100644 --- a/src/doc/rustc-dev-guide/src/hir.md +++ b/src/doc/rustc-dev-guide/src/hir.md @@ -139,12 +139,12 @@ defined in the map. By matching on this, you can find out what sort of node the `HirId` referred to and also get a pointer to the data itself. Often, you know what sort of node `n` is – e.g. if you know that `n` must be some HIR expression, you can do -[`tcx.hir().expect_expr(n)`][expect_expr], which will extract and return the +[`tcx.hir_expect_expr(n)`][expect_expr], which will extract and return the [`&hir::Expr`][Expr], panicking if `n` is not in fact an expression. [find]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.find [`Node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html -[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.expect_expr +[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.expect_expr [Expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Expr.html Finally, you can use the HIR map to find the parents of nodes, via diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 8c6ea00d4890d..e973b89b2375b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -181,7 +181,7 @@ pub(crate) fn try_inline_glob( .filter_map(|child| child.res.opt_def_id()) .filter(|def_id| !cx.tcx.is_doc_hidden(def_id)) .collect(); - let attrs = cx.tcx.hir().attrs(import.hir_id()); + let attrs = cx.tcx.hir_attrs(import.hir_id()); let mut items = build_module_items( cx, did, @@ -455,7 +455,7 @@ pub(crate) fn build_impl( } let impl_item = match did.as_local() { - Some(did) => match &tcx.hir().expect_item(did).kind { + Some(did) => match &tcx.hir_expect_item(did).kind { hir::ItemKind::Impl(impl_) => Some(impl_), _ => panic!("`DefID` passed to `build_impl` is not an `impl"), }, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 97ff4c2ef4096..b213be5747beb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -112,7 +112,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< items.extend(doc.inlined_foreigns.iter().flat_map(|((_, renamed), (res, local_import_id))| { let Some(def_id) = res.opt_def_id() else { return Vec::new() }; let name = renamed.unwrap_or_else(|| cx.tcx.item_name(def_id)); - let import = cx.tcx.hir().expect_item(*local_import_id); + let import = cx.tcx.hir_expect_item(*local_import_id); match import.kind { hir::ItemKind::Use(path, kind) => { let hir::UsePath { segments, span, .. } = *path; @@ -125,7 +125,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< items.extend(doc.items.values().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { - let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); + let name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted) } else { // skip everything else @@ -986,7 +986,7 @@ fn clean_proc_macro<'tcx>( kind: MacroKind, cx: &mut DocContext<'tcx>, ) -> ItemKind { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); if kind == MacroKind::Derive && let Some(derive_name) = hir_attr_lists(attrs, sym::proc_macro_derive).find_map(|mi| mi.ident()) @@ -1019,7 +1019,7 @@ fn clean_fn_or_proc_macro<'tcx>( name: &mut Symbol, cx: &mut DocContext<'tcx>, ) -> ItemKind { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let macro_kind = attrs.iter().find_map(|a| { if a.has_name(sym::proc_macro) { Some(MacroKind::Bang) @@ -1756,7 +1756,7 @@ fn maybe_expand_private_type_alias<'tcx>( let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id()) && !cx.current_type_aliases.contains_key(&def_id.to_def_id()) { - &cx.tcx.hir().expect_item(def_id).kind + &cx.tcx.hir_expect_item(def_id).kind } else { return None; }; @@ -2762,7 +2762,7 @@ fn clean_maybe_renamed_item<'tcx>( use hir::ItemKind; let def_id = item.owner_id.to_def_id(); - let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); + let mut name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); cx.with_param_env(def_id, |cx| { let kind = match item.kind { ItemKind::Static(ty, mutability, body_id) => StaticItem(Static { @@ -2937,7 +2937,7 @@ fn clean_extern_crate<'tcx>( let cnum = cx.tcx.extern_mod_stmt_cnum(krate.owner_id.def_id).unwrap_or(LOCAL_CRATE); // this is the ID of the crate itself let crate_def_id = cnum.as_def_id(); - let attrs = cx.tcx.hir().attrs(krate.hir_id()); + let attrs = cx.tcx.hir_attrs(krate.hir_id()); let ty_vis = cx.tcx.visibility(krate.owner_id); let please_inline = ty_vis.is_public() && attrs.iter().any(|a| { @@ -3006,7 +3006,7 @@ fn clean_use_statement_inner<'tcx>( } let visibility = cx.tcx.visibility(import.owner_id); - let attrs = cx.tcx.hir().attrs(import.hir_id()); + let attrs = cx.tcx.hir_attrs(import.hir_id()); let inline_attr = hir_attr_lists(attrs, sym::doc).get_word_attr(sym::inline); let pub_underscore = visibility.is_public() && name == kw::Underscore; let current_mod = cx.tcx.parent_module_from_def_id(import.owner_id.def_id); diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 88af9a7388cea..f7f0c9766e2f6 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -216,7 +216,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); - let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(CRATE_HIR_ID); let opts = scrape_test_config(crate_name, crate_attrs, args_path); let enable_per_target_ignores = options.enable_per_target_ignores; diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 907e2a3eb2fcd..18ad442d01789 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -95,7 +95,7 @@ impl HirCollector<'_> { sp: Span, nested: F, ) { - let ast_attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); + let ast_attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id)); if let Some(ref cfg) = extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default()) && !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features())) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index edfcc1291b976..4150c5609a97e 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1,5 +1,5 @@ // Local js definitions: -/* global addClass, getSettingValue, hasClass, searchState, updateLocalStorage */ +/* global addClass, getSettingValue, hasClass, updateLocalStorage */ /* global onEachLazy, removeClass, getVar */ "use strict"; @@ -121,12 +121,9 @@ function getNakedUrl() { * doesn't have a parent node. * * @param {HTMLElement} newNode - * @param {HTMLElement} referenceNode + * @param {HTMLElement & { parentNode: HTMLElement }} referenceNode */ function insertAfter(newNode, referenceNode) { - // You're not allowed to pass an element with no parent. - // I dunno how to make TS's typechecker see that. - // @ts-expect-error referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } @@ -305,11 +302,10 @@ function preLoadCss(cssUrl) { window.searchState.timeout = null; } }, - // @ts-expect-error isDisplayed: () => { const outputElement = window.searchState.outputElement(); - return outputElement && - outputElement.parentElement && + return !!outputElement && + !!outputElement.parentElement && outputElement.parentElement.id === ALTERNATIVE_DISPLAY_ID; }, // Sets the focus on the search bar at the top of the page @@ -325,8 +321,6 @@ function preLoadCss(cssUrl) { search = window.searchState.outputElement(); } switchDisplayedElement(search); - // @ts-expect-error - window.searchState.mouseMovedAfterSearch = false; document.title = window.searchState.title; }, removeQueryParameters: () => { @@ -503,34 +497,40 @@ function preLoadCss(cssUrl) { handleHashes(ev); } - // @ts-expect-error + /** + * @param {HTMLElement|null} elem + */ function openParentDetails(elem) { while (elem) { if (elem.tagName === "DETAILS") { + // @ts-expect-error elem.open = true; } - elem = elem.parentNode; + elem = elem.parentElement; } } - // @ts-expect-error + /** + * @param {string} id + */ function expandSection(id) { openParentDetails(document.getElementById(id)); } - // @ts-expect-error + /** + * @param {KeyboardEvent} ev + */ function handleEscape(ev) { - // @ts-expect-error - searchState.clearInputTimeout(); - // @ts-expect-error - searchState.hideResults(); + window.searchState.clearInputTimeout(); + window.searchState.hideResults(); ev.preventDefault(); - // @ts-expect-error - searchState.defocus(); + window.searchState.defocus(); window.hideAllModals(true); // true = reset focus for tooltips } - // @ts-expect-error + /** + * @param {KeyboardEvent} ev + */ function handleShortcut(ev) { // Don't interfere with browser shortcuts const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; @@ -538,8 +538,8 @@ function preLoadCss(cssUrl) { return; } - // @ts-expect-error - if (document.activeElement.tagName === "INPUT" && + if (document.activeElement && + document.activeElement.tagName === "INPUT" && // @ts-expect-error document.activeElement.type !== "checkbox" && // @ts-expect-error @@ -559,8 +559,7 @@ function preLoadCss(cssUrl) { case "S": case "/": ev.preventDefault(); - // @ts-expect-error - searchState.focus(); + window.searchState.focus(); break; case "+": @@ -586,7 +585,6 @@ function preLoadCss(cssUrl) { document.addEventListener("keydown", handleShortcut); function addSidebarItems() { - // @ts-expect-error if (!window.SIDEBAR_ITEMS) { return; } @@ -675,7 +673,6 @@ function preLoadCss(cssUrl) { } // - // @ts-expect-error window.register_implementors = imp => { const implementors = document.getElementById("implementors-list"); const synthetic_implementors = document.getElementById("synthetic-implementors-list"); @@ -767,9 +764,7 @@ function preLoadCss(cssUrl) { } } }; - // @ts-expect-error if (window.pending_implementors) { - // @ts-expect-error window.register_implementors(window.pending_implementors); } @@ -802,16 +797,14 @@ function preLoadCss(cssUrl) { * * - After processing all of the impls, it sorts the sidebar items by name. * - * @param {{[cratename: string]: Array>}} imp + * @param {rustdoc.TypeImpls} imp */ - // @ts-expect-error window.register_type_impls = imp => { // @ts-expect-error if (!imp || !imp[window.currentCrate]) { return; } - // @ts-expect-error - window.pending_type_impls = null; + window.pending_type_impls = undefined; const idMap = new Map(); let implementations = document.getElementById("implementations-list"); @@ -997,9 +990,7 @@ function preLoadCss(cssUrl) { list.replaceChildren(...newChildren); } }; - // @ts-expect-error if (window.pending_type_impls) { - // @ts-expect-error window.register_type_impls(window.pending_type_impls); } @@ -1695,8 +1686,7 @@ function preLoadCss(cssUrl) { addSidebarCrates(); onHashChange(null); window.addEventListener("hashchange", onHashChange); - // @ts-expect-error - searchState.setup(); + window.searchState.setup(); }()); // Hide, show, and resize the sidebar diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 1554c045a3271..4b43c00730d47 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -7,6 +7,8 @@ declare global { interface Window { /** Make the current theme easy to find */ currentTheme: HTMLLinkElement|null; + /** Generated in `render/context.rs` */ + SIDEBAR_ITEMS?: { [key: string]: string[] }; /** Used by the popover tooltip code. */ RUSTDOC_TOOLTIP_HOVER_MS: number; /** Used by the popover tooltip code. */ @@ -42,6 +44,17 @@ declare global { * Set up event listeners for a scraped source example. */ updateScrapedExample?: function(HTMLElement, HTMLElement), + /** + * register trait implementors, called by code generated in + * `write_shared.rs` + */ + register_implementors?: function(rustdoc.Implementors): void, + /** + * fallback in case `register_implementors` isn't defined yet. + */ + pending_implementors?: rustdoc.Implementors, + register_type_impls?: function(rustdoc.TypeImpls): void, + pending_type_impls?: rustdoc.TypeImpls, } interface HTMLElement { /** Used by the popover tooltip code. */ @@ -413,4 +426,16 @@ declare namespace rustdoc { }; type VlqData = VlqData[] | number; + + /** + * Maps from crate names to trait implementation data. + * Provied by generated `trait.impl` files. + */ + type Implementors = { + [key: string]: Array<[string, number, Array]> + } + + type TypeImpls = { + [cratename: string]: Array> + } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 7b6921afa0808..68e381fa3f171 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -143,7 +143,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { && self.cx.tcx.has_attr(def_id, sym::macro_export) && inserted.insert(def_id) { - let item = self.cx.tcx.hir().expect_item(local_def_id); + let item = self.cx.tcx.hir_expect_item(local_def_id); top_level_module .items .insert((local_def_id, Some(item.ident.name)), (item, None, None)); @@ -153,8 +153,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.cx.cache.hidden_cfg = self .cx .tcx - .hir() - .attrs(CRATE_HIR_ID) + .hir_attrs(CRATE_HIR_ID) .iter() .filter(|attr| attr.has_name(sym::doc)) .flat_map(|attr| attr.meta_item_list().into_iter().flatten()) @@ -245,7 +244,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; let document_hidden = self.cx.render_options.document_hidden; - let use_attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(def_id)); + let use_attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. let is_no_inline = hir_attr_lists(use_attrs, sym::doc).has_word(sym::no_inline) || (document_hidden && hir_attr_lists(use_attrs, sym::doc).has_word(sym::hidden)); @@ -449,7 +448,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { continue; } - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(item.owner_id.def_id)); + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(item.owner_id.def_id)); // If there was a private module in the current path then don't bother inlining // anything as it will probably be stripped anyway. diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index 2b59c218d57a1..f9a2f011a144f 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -465,7 +465,7 @@ impl Attributes { impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); if is_relevant_item(cx, item) { inline_always::check(cx, item.span, item.ident.name, attrs); } @@ -474,13 +474,13 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { if is_relevant_impl(cx, item) { - inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())); + inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id())); } } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if is_relevant_trait(cx, item) { - inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())); + inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id())); } } } diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs index 085ed9222c91a..7c64bf46e7bd2 100644 --- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs +++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs @@ -97,7 +97,7 @@ fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: ty::GenericArgsR } fn has_c_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); find_attr!(attrs, AttributeKind::Repr(r) if r.iter().any(|(x, _)| *x == ReprAttr::ReprC)) } diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 66a3e5e3d3c7f..8d9222e4bf61e 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -197,9 +197,9 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() - && let attrs = cx.tcx.hir().attrs(item.hir_id()) + && let attrs = cx.tcx.hir_attrs(item.hir_id()) && !attrs.iter().any(|attr| attr.doc_str().is_some()) - && cx.tcx.hir().attrs(impl_item_hir).is_empty() + && cx.tcx.hir_attrs(impl_item_hir).is_empty() { if adt_def.is_struct() { check_struct(cx, item, self_ty, func_expr, adt_def, args, cx.tcx.typeck_body(*b)); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index db3e6034c5baf..2ae35b4005579 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -384,7 +384,7 @@ fn check_unsafe_derive_deserialize<'tcx>( .tcx .inherent_impls(def.did()) .iter() - .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local())) + .map(|imp_did| cx.tcx.hir_expect_item(imp_did.expect_local())) .any(|imp| has_unsafe(cx, imp)) { span_lint_hir_and_then( diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs index e8638595c4b26..e75abf28bace8 100644 --- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs +++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs @@ -25,7 +25,7 @@ pub fn check( && cx .tcx .hir_parent_iter(owner_id.into()) - .any(|(id, _node)| is_doc_hidden(cx.tcx.hir().attrs(id))) + .any(|(id, _node)| is_doc_hidden(cx.tcx.hir_attrs(id))) { return; } diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 33ba401d60c21..9298f56b68bee 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -163,7 +163,6 @@ impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> { fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) { if cmt.place.projections.is_empty() { - let map = &self.cx.tcx.hir(); if is_argument(self.cx.tcx, cmt.hir_id) { // Skip closure arguments let parent_id = self.cx.tcx.parent_hir_id(cmt.hir_id); @@ -174,7 +173,7 @@ impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> { // skip if there is a `self` parameter binding to a type // that contains `Self` (i.e.: `self: Box`), see #4804 if let Some(trait_self_ty) = self.trait_self_ty { - if map.name(cmt.hir_id) == kw::SelfLower && cmt.place.ty().contains(trait_self_ty) { + if self.cx.tcx.hir_name(cmt.hir_id) == kw::SelfLower && cmt.place.ty().contains(trait_self_ty) { return; } } diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs index 9bf3baba4b597..591912cc8d5e8 100644 --- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs @@ -84,7 +84,7 @@ impl LateLintPass<'_> for ExhaustiveItems { _ => return, }; if cx.effective_visibilities.is_exported(item.owner_id.def_id) - && let attrs = cx.tcx.hir().attrs(item.hir_id()) + && let attrs = cx.tcx.hir_attrs(item.hir_id()) && !attrs.iter().any(|a| a.has_name(sym::non_exhaustive)) && fields.iter().all(|f| cx.tcx.visibility(f.def_id).is_public()) { diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs index ff75fcf2b417c..5b42a40d850bb 100644 --- a/src/tools/clippy/clippy_lints/src/format_impl.rs +++ b/src/tools/clippy/clippy_lints/src/format_impl.rs @@ -209,9 +209,8 @@ impl FormatImplExpr<'_, '_> { // Handle dereference of &self -> self that is equivalent (i.e. via *self in fmt() impl) // Since the argument to fmt is itself a reference: &self let reference = peel_ref_operators(self.cx, arg); - let map = self.cx.tcx.hir(); // Is the reference self? - if path_to_local(reference).map(|x| map.name(x)) == Some(kw::SelfLower) { + if path_to_local(reference).map(|x| self.cx.tcx.hir_name(x)) == Some(kw::SelfLower) { let FormatTraitNames { name, .. } = self.format_trait_impl; span_lint( self.cx, diff --git a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs index 0bdb99d7b9a4d..8822b87f92f72 100644 --- a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs +++ b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs @@ -43,8 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for FourForwardSlashes { let sm = cx.sess().source_map(); let mut span = cx .tcx - .hir() - .attrs(item.hir_id()) + .hir_attrs(item.hir_id()) .iter() .filter(|i| i.is_doc_comment()) .fold(item.span.shrink_to_lo(), |span, attr| span.to(attr.span())); diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index f1c9657f22404..c3e0d5e8b694d 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -21,7 +21,7 @@ use core::ops::ControlFlow; use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT}; pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let hir::ItemKind::Fn { ref sig, @@ -51,7 +51,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp if let hir::ImplItemKind::Fn(ref sig, ref body_id) = item.kind { let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); @@ -74,7 +74,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); diff --git a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs index 5b58113169b1e..e1dd7872b9d48 100644 --- a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs +++ b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs @@ -182,7 +182,7 @@ fn suggestion<'tcx>( } fn field_with_attrs_span(tcx: TyCtxt<'_>, field: &hir::ExprField<'_>) -> Span { - if let Some(attr) = tcx.hir().attrs(field.hir_id).first() { + if let Some(attr) = tcx.hir_attrs(field.hir_id).first() { field.span.with_lo(attr.span().lo()) } else { field.span diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs index 9b4a3b3f9c84c..6a436fb4a9d1e 100644 --- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs +++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs @@ -34,8 +34,7 @@ impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody { if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind && let Some(attr) = cx .tcx - .hir() - .attrs(item.hir_id()) + .hir_attrs(item.hir_id()) .iter() .find(|a| a.has_name(sym::inline)) { diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 20be22850b760..b712b351d063c 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -98,7 +98,7 @@ impl LateLintPass<'_> for MacroUseImports { if cx.sess().opts.edition >= Edition::Edition2018 && let hir::ItemKind::Use(path, _kind) = &item.kind && let hir_id = item.hir_id() - && let attrs = cx.tcx.hir().attrs(hir_id) + && let attrs = cx.tcx.hir_attrs(hir_id) && let Some(mac_attr) = attrs.iter().find(|attr| attr.has_name(sym::macro_use)) && let Some(id) = path.res.iter().find_map(|res| match res { Res::Def(DefKind::Mod, id) => Some(id), diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 496e0660d4f9a..64b07a5536b4d 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -89,11 +89,11 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { match item.kind { ItemKind::Enum(def, _) if def.variants.len() > 1 => { let iter = def.variants.iter().filter_map(|v| { - (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir().attrs(v.hir_id))) + (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id))) .then_some((v.def_id, v.span)) }); if let Ok((id, span)) = iter.exactly_one() - && !attr::contains_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive) + && !attr::contains_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); } @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { "this seems like a manual implementation of the non-exhaustive pattern", |diag| { if let Some(non_exhaustive) = - attr::find_by_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive) + attr::find_by_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) { diag.span_note(non_exhaustive.span(), "the struct is already non-exhaustive"); } else { diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs index d697f427c7052..d29d1ea3e96d9 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs @@ -42,7 +42,7 @@ pub(super) fn check_match<'tcx>( cx, scrutinee, arms.iter() - .map(|arm| (cx.tcx.hir().attrs(arm.hir_id), Some(arm.pat), arm.body, arm.guard)), + .map(|arm| (cx.tcx.hir_attrs(arm.hir_id), Some(arm.pat), arm.body, arm.guard)), e, false, ) diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index 41e4c75f843e5..250f17fa9025a 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -75,7 +75,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { HirIdMapEntry::Occupied(entry) => return *entry.get() == b_id, } // the names technically don't have to match; this makes the lint more conservative - && cx.tcx.hir().name(a_id) == cx.tcx.hir().name(b_id) + && cx.tcx.hir_name(a_id) == cx.tcx.hir_name(b_id) && cx.typeck_results().expr_ty(a) == cx.typeck_results().expr_ty(b) && pat_contains_local(lhs.pat, a_id) && pat_contains_local(rhs.pat, b_id) diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs index 1c64f78678aeb..7c190e123b72e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs +++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs @@ -41,7 +41,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool { cx.tcx .hir_parent_id_iter(id) - .any(|id| cx.tcx.hir().attrs(id).iter().any(|attr| attr.has_name(sym::cfg))) + .any(|id| cx.tcx.hir_attrs(id).iter().any(|attr| attr.has_name(sym::cfg))) } /// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 94d3657d9f123..7dde21d3edb13 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -4731,7 +4731,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { } let name = impl_item.ident.name.as_str(); let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let item = cx.tcx.hir().expect_item(parent); + let item = cx.tcx.hir_expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })); diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 47a9e17b3cfe1..3470c266c4917 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_crate(&mut self, cx: &LateContext<'tcx>) { - let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID); + let attrs = cx.tcx.hir_attrs(hir::CRATE_HIR_ID); self.check_missing_docs_attrs(cx, CRATE_DEF_ID, attrs, cx.tcx.def_span(CRATE_DEF_ID), "the", "crate"); } @@ -224,7 +224,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id()); - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); if !is_from_proc_macro(cx, it) { self.check_missing_docs_attrs(cx, it.owner_id.def_id, attrs, it.span, article, desc); } @@ -234,7 +234,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) { let (article, desc) = cx.tcx.article_and_description(trait_item.owner_id.to_def_id()); - let attrs = cx.tcx.hir().attrs(trait_item.hir_id()); + let attrs = cx.tcx.hir_attrs(trait_item.hir_id()); if !is_from_proc_macro(cx, trait_item) { self.check_missing_docs_attrs(cx, trait_item.owner_id.def_id, attrs, trait_item.span, article, desc); } @@ -252,7 +252,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id()); - let attrs = cx.tcx.hir().attrs(impl_item.hir_id()); + let attrs = cx.tcx.hir_attrs(impl_item.hir_id()); if !is_from_proc_macro(cx, impl_item) { self.check_missing_docs_attrs(cx, impl_item.owner_id.def_id, attrs, impl_item.span, article, desc); } @@ -261,7 +261,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_field_def(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::FieldDef<'_>) { if !sf.is_positional() { - let attrs = cx.tcx.hir().attrs(sf.hir_id); + let attrs = cx.tcx.hir_attrs(sf.hir_id); if !is_from_proc_macro(cx, sf) { self.check_missing_docs_attrs(cx, sf.def_id, attrs, sf.span, "a", "struct field"); } @@ -270,7 +270,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) { - let attrs = cx.tcx.hir().attrs(v.hir_id); + let attrs = cx.tcx.hir_attrs(v.hir_id); if !is_from_proc_macro(cx, v) { self.check_missing_docs_attrs(cx, v.def_id, attrs, v.span, "a", "variant"); } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 3cf1a80607e8b..2c578d816025f 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { match it.kind { hir::ItemKind::Fn { .. } => { let desc = "a function"; - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); check_missing_inline_attrs(cx, attrs, it.span, desc); }, hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _generics, _bounds, trait_items) => { @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { // an impl is not provided let desc = "a default trait method"; let item = cx.tcx.hir_trait_item(tit.id); - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); check_missing_inline_attrs(cx, attrs, item.span, desc); } }, @@ -168,7 +168,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { } } - let attrs = cx.tcx.hir().attrs(impl_item.hir_id()); + let attrs = cx.tcx.hir_attrs(impl_item.hir_id()); check_missing_inline_attrs(cx, attrs, impl_item.span, desc); } } diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index a7452c8a3c84e..be728e6c8b74b 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -334,7 +334,7 @@ impl<'tcx> Visitor<'tcx> for ReadVisitor<'_, 'tcx> { self.cx, MIXED_READ_WRITE_IN_EXPRESSION, expr.span, - format!("unsequenced read of `{}`", self.cx.tcx.hir().name(self.var)), + format!("unsequenced read of `{}`", self.cx.tcx.hir_name(self.var)), |diag| { diag.span_note( self.write_expr.span, diff --git a/src/tools/clippy/clippy_lints/src/needless_if.rs b/src/tools/clippy/clippy_lints/src/needless_if.rs index 7eefb016aca98..c90019f6ee161 100644 --- a/src/tools/clippy/clippy_lints/src/needless_if.rs +++ b/src/tools/clippy/clippy_lints/src/needless_if.rs @@ -65,7 +65,7 @@ impl LateLintPass<'_> for NeedlessIf { stmt.span, "this `if` branch is empty", "you can remove it", - if cond.can_have_side_effects() || !cx.tcx.hir().attrs(stmt.hir_id).is_empty() { + if cond.can_have_side_effects() || !cx.tcx.hir_attrs(stmt.hir_id).is_empty() { // `{ foo }` or `{ foo } && bar` placed into a statement position would be // interpreted as a block statement, force it to be an expression if cond_snippet.starts_with('{') { diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs index 863a1f895c937..3efbed0c2365e 100644 --- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs +++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs @@ -261,7 +261,7 @@ fn check<'tcx>( binding_id: HirId, ) -> Option<()> { let usage = first_usage(cx, binding_id, local_stmt.hir_id, block)?; - let binding_name = cx.tcx.hir().opt_name(binding_id)?; + let binding_name = cx.tcx.hir_opt_name(binding_id)?; let let_snippet = local_snippet_without_semicolon(cx, local)?; match usage.expr.kind { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index dc10de24bc8c7..576bb27b254c9 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -147,7 +147,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { // We don't check unsafe functions. return; } - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) { return; } diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index dc85176ebb9e9..7bee89086b80f 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { match kind { FnKind::ItemFn(.., header) => { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) { return; } diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs index 1baa3cb2f0fdc..fe8a02c64c660 100644 --- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -40,7 +40,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { if let ItemKind::Fn { sig: fn_sig, .. } = &item.kind && !item.span.from_expansion() { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let mut app = Applicability::MaybeIncorrect; let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(item.ident.span.lo()), "..", &mut app); for attr in attrs { diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index d4da12451f181..9b53608ae7f3c 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -351,7 +351,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { if let ImplItemKind::Const(_, body_id) = &impl_item.kind { let item_def_id = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let item = cx.tcx.hir().expect_item(item_def_id); + let item = cx.tcx.hir_expect_item(item_def_id); match &item.kind { ItemKind::Impl(Impl { diff --git a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs index c3c09946c27d1..378fed481f4fe 100644 --- a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs +++ b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs @@ -181,7 +181,7 @@ fn in_impl<'tcx>( ) -> Option<(&'tcx rustc_hir::Ty<'tcx>, &'tcx rustc_hir::Ty<'tcx>)> { if let Some(block) = get_enclosing_block(cx, e.hir_id) && let Some(impl_def_id) = cx.tcx.impl_of_method(block.hir_id.owner.to_def_id()) - && let item = cx.tcx.hir().expect_item(impl_def_id.expect_local()) + && let item = cx.tcx.hir_expect_item(impl_def_id.expect_local()) && let ItemKind::Impl(item) = &item.kind && let Some(of_trait) = &item.of_trait && let Some(seg) = of_trait.path.segments.last() @@ -200,7 +200,7 @@ fn in_impl<'tcx>( fn are_equal(cx: &LateContext<'_>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool { if let ty::Adt(adt_def, _) = middle_ty.kind() && let Some(local_did) = adt_def.did().as_local() - && let item = cx.tcx.hir().expect_item(local_did) + && let item = cx.tcx.hir_expect_item(local_did) && let middle_ty_id = item.owner_id.to_def_id() && let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind && let Res::Def(_, hir_ty_id) = path.res diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 49bc560834682..320c0286bb7be 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -280,7 +280,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { if header.abi != ExternAbi::Rust { return; } - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); for a in attrs { if let Some(meta_items) = a.meta_item_list() { if a.has_name(sym::proc_macro_derive) diff --git a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs index db03657c9af43..fd21893232dbb 100644 --- a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs +++ b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields { // Only pertains to fields that start with an underscore, and are public. if field.ident.as_str().starts_with('_') && is_visible(field) // We ignore fields that have `#[doc(hidden)]`. - && !is_doc_hidden(cx.tcx.hir().attrs(field.hir_id)) + && !is_doc_hidden(cx.tcx.hir_attrs(field.hir_id)) // We ignore fields that are `PhantomData`. && !is_path_lang_item(cx, field.ty, LangItem::PhantomData) { diff --git a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs index 6bd68dd4109d4..49b522994fbf7 100644 --- a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs +++ b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs @@ -93,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec { }, ), VecInitKind::WithExprCapacity(hir_id) => { - let e = cx.tcx.hir().expect_expr(hir_id); + let e = cx.tcx.hir_expect_expr(hir_id); span_lint_hir_and_then( cx, READ_ZERO_BYTE_VEC, diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs index 5a25483c397c6..07ae92fa98439 100644 --- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs +++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs @@ -74,7 +74,7 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa // We only show this warning for public exported methods. && cx.effective_visibilities.is_exported(fn_def) // We don't want to emit this lint if the `#[must_use]` attribute is already there. - && !cx.tcx.hir().attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use)) + && !cx.tcx.hir_attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use)) && cx.tcx.visibility(fn_def.to_def_id()).is_public() && let ret_ty = return_ty(cx, owner_id) && let self_arg = nth_arg(cx, owner_id, 0) diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index 3ba6d6284592b..4cb73df8b488f 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -231,7 +231,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { && let Some(stmt) = block.stmts.iter().last() && let StmtKind::Let(local) = &stmt.kind && local.ty.is_none() - && cx.tcx.hir().attrs(local.hir_id).is_empty() + && cx.tcx.hir_attrs(local.hir_id).is_empty() && let Some(initexpr) = &local.init && let PatKind::Binding(_, local_id, _, _) = local.pat.kind && path_to_local_id(retexpr, local_id) @@ -401,7 +401,7 @@ fn check_final_expr<'tcx>( // This allows the addition of attributes, like `#[allow]` (See: clippy#9361) // `#[expect(clippy::needless_return)]` needs to be handled separately to // actually fulfill the expectation (clippy::#12998) - match cx.tcx.hir().attrs(expr.hir_id) { + match cx.tcx.hir_attrs(expr.hir_id) { [] => {}, [attr] => { if matches!(Level::from_attr(attr), Some(Level::Expect(_))) diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index fc02c3a51716e..8b2d597b9e323 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { } let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let item = cx.tcx.hir().expect_item(parent); + let item = cx.tcx.hir_expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let ret_ty = return_ty(cx, impl_item.owner_id); diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 746bf018bcc31..be533ca915ed4 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -429,8 +429,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span { span.to(cx .tcx - .hir() - .attrs(hir_id) + .hir_attrs(hir_id) .iter() .fold(span, |acc, attr| acc.to(attr.span()))) } diff --git a/src/tools/clippy/clippy_lints/src/unused_self.rs b/src/tools/clippy/clippy_lints/src/unused_self.rs index 2c6c75693166f..582aa6e6001e8 100644 --- a/src/tools/clippy/clippy_lints/src/unused_self.rs +++ b/src/tools/clippy/clippy_lints/src/unused_self.rs @@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { return; } let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let parent_item = cx.tcx.hir().expect_item(parent); + let parent_item = cx.tcx.hir_expect_item(parent); let assoc_item = cx.tcx.associated_item(impl_item.owner_id); let contains_todo = |cx, body: &'_ Body<'_>| -> bool { clippy_utils::visitors::for_each_expr_without_closures(body.value, |e| { diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 6f6683eb97123..b466a8e127a94 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -318,7 +318,7 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> { { if call_to_unwrap == unwrappable.safe_to_unwrap { let is_entire_condition = unwrappable.is_entire_condition; - let unwrappable_variable_name = self.cx.tcx.hir().name(unwrappable.local_id); + let unwrappable_variable_name = self.cx.tcx.hir_name(unwrappable.local_id); let suggested_pattern = if call_to_unwrap { unwrappable.kind.success_variant_pattern() } else { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 9d8c161873c05..4309cd2c9abdf 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -793,7 +793,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { } fn has_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); get_attr(cx.sess(), attrs, "author").count() > 0 } diff --git a/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs b/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs index b108951978f30..9910be9bc2853 100644 --- a/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs +++ b/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs @@ -59,6 +59,6 @@ impl<'tcx> LateLintPass<'tcx> for DumpHir { } fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); get_attr(cx.sess(), attrs, "dump").count() > 0 } diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index 89b4c48b8b116..16d51fa09025a 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -247,7 +247,7 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<' /// This function extracts the version value of a `clippy::version` attribute if the given value has /// one pub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Option { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); attrs.iter().find_map(|attr| { if let hir::Attribute::Unparsed(attr_kind) = &attr // Identify attribute diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index d89692468441c..80613a51c1400 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2036,15 +2036,14 @@ pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool { } pub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - find_attr!(cx.tcx.hir().attrs(hir_id), AttributeKind::Repr(..)) + find_attr!(cx.tcx.hir_attrs(hir_id), AttributeKind::Repr(..)) } pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool { - let map = &tcx.hir(); let mut prev_enclosing_node = None; let mut enclosing_node = node; while Some(enclosing_node) != prev_enclosing_node { - if has_attr(map.attrs(enclosing_node), symbol) { + if has_attr(tcx.hir_attrs(enclosing_node), symbol) { return true; } prev_enclosing_node = Some(enclosing_node); @@ -2061,7 +2060,7 @@ pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool { .filter(|(_, node)| matches!(node, OwnerNode::Item(item) if matches!(item.kind, ItemKind::Impl(_)))) .any(|(id, _)| { has_attr( - tcx.hir().attrs(tcx.local_def_id_to_hir_id(id.def_id)), + tcx.hir_attrs(tcx.local_def_id_to_hir_id(id.def_id)), sym::automatically_derived, ) }) @@ -2344,16 +2343,14 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> { pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { cx.tcx - .hir() - .attrs(hir::CRATE_HIR_ID) + .hir_attrs(hir::CRATE_HIR_ID) .iter() .any(|attr| attr.name_or_empty() == sym::no_std) } pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { cx.tcx - .hir() - .attrs(hir::CRATE_HIR_ID) + .hir_attrs(hir::CRATE_HIR_ID) .iter() .any(|attr| attr.name_or_empty() == sym::no_core) } @@ -2643,8 +2640,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym // We could also check for the type name `test::TestDescAndFn` if let Res::Def(DefKind::Struct, _) = path.res { let has_test_marker = tcx - .hir() - .attrs(item.hir_id()) + .hir_attrs(item.hir_id()) .iter() .any(|a| a.has_name(sym::rustc_test_marker)); if has_test_marker { @@ -2688,7 +2684,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool { /// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent /// use [`is_in_cfg_test`] pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.hir().attrs(id).iter().any(|attr| { + tcx.hir_attrs(id).iter().any(|attr| { if attr.has_name(sym::cfg) && let Some(items) = attr.meta_item_list() && let [item] = &*items @@ -2713,12 +2709,10 @@ pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied. pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - let hir = tcx.hir(); - tcx.has_attr(def_id, sym::cfg) || tcx .hir_parent_iter(tcx.local_def_id_to_hir_id(def_id)) - .flat_map(|(parent_id, _)| hir.attrs(parent_id)) + .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)) .any(|attr| attr.has_name(sym::cfg)) } diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs index 5bb2b12988a6c..0316de172de7f 100644 --- a/src/tools/clippy/clippy_utils/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -108,7 +108,7 @@ impl Msrv { let start = cx.last_node_with_lint_attrs; if let Some(msrv_attr) = once(start) .chain(cx.tcx.hir_parent_id_iter(start)) - .find_map(|id| parse_attrs(cx.tcx.sess, cx.tcx.hir().attrs(id))) + .find_map(|id| parse_attrs(cx.tcx.sess, cx.tcx.hir_attrs(id))) { return Some(msrv_attr); } diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 24b4f0d9e6d81..9cc66593dcc3f 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -847,7 +847,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { let mut start_snip = snippet_with_applicability(self.cx, start_span, "..", &mut self.applicability); // identifier referring to the variable currently triggered (i.e.: `fp`) - let ident_str = map.name(id).to_string(); + let ident_str = self.cx.tcx.hir_name(id).to_string(); // full identifier that includes projection (i.e.: `fp.field`) let ident_str_with_proj = snippet(self.cx, span, "..").to_string(); @@ -876,7 +876,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { // item is used in a call // i.e.: `Call`: `|x| please(x)` or `MethodCall`: `|x| [1, 2, 3].contains(x)` ExprKind::Call(_, call_args) | ExprKind::MethodCall(_, _, call_args, _) => { - let expr = self.cx.tcx.hir().expect_expr(cmt.hir_id); + let expr = self.cx.tcx.hir_expect_expr(cmt.hir_id); let arg_ty_kind = self.cx.typeck_results().expr_ty(expr).kind(); if matches!(arg_ty_kind, ty::Ref(_, _, Mutability::Not)) { diff --git a/tests/mir-opt/global_asm.rs b/tests/mir-opt/global_asm.rs new file mode 100644 index 0000000000000..22b782d365e94 --- /dev/null +++ b/tests/mir-opt/global_asm.rs @@ -0,0 +1,9 @@ +// skip-filecheck +//@ needs-asm-support + +// `global_asm!` gets a fake body, make sure it is handled correctly + +// EMIT_MIR global_asm.{global_asm#0}.SimplifyLocals-final.after.mir +core::arch::global_asm!("/* */"); + +fn main() {} diff --git a/tests/mir-opt/global_asm.{global_asm#0}.SimplifyLocals-final.after.mir b/tests/mir-opt/global_asm.{global_asm#0}.SimplifyLocals-final.after.mir new file mode 100644 index 0000000000000..cec3c4a8261e6 --- /dev/null +++ b/tests/mir-opt/global_asm.{global_asm#0}.SimplifyLocals-final.after.mir @@ -0,0 +1,9 @@ +// MIR for `{global_asm#0}` after SimplifyLocals-final + +{global_asm#0}: ! = { + let mut _0: !; + + bb0: { + asm!("/* */", options()) -> unwind unreachable; + } +} diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.rs b/tests/ui/const-generics/const-param-type-depends-on-const-param.rs index ee0e1326baa87..3372ea5b85313 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.rs +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.rs @@ -9,11 +9,11 @@ // We may want to lift this restriction in the future. pub struct Dependent([(); N]); -//~^ ERROR: the type of const parameters must not depend on other generic parameters -//[min]~^^ ERROR `[u8; N]` is forbidden +//~^ ERROR the type of const parameters must not depend on other generic parameters +//[min]~^^ ERROR `[u8; N]` is forbidden as the type of a const generic parameter pub struct SelfDependent; -//~^ ERROR: the type of const parameters must not depend on other generic parameters -//[min]~^^ ERROR `[u8; N]` is forbidden +//~^ ERROR the type of const parameters must not depend on other generic parameters +//[min]~^^ ERROR `[u8; N]` is forbidden as the type of a const generic parameter fn main() {} diff --git a/tests/ui/const-generics/const-param-type-depends-on-parent-param.rs b/tests/ui/const-generics/const-param-type-depends-on-parent-param.rs new file mode 100644 index 0000000000000..83fe8c139f90d --- /dev/null +++ b/tests/ui/const-generics/const-param-type-depends-on-parent-param.rs @@ -0,0 +1,8 @@ +#![feature(adt_const_params)] + +trait Trait { + fn foo() {} + //~^ ERROR the type of const parameters must not depend on other generic parameters +} + +fn main() {} diff --git a/tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr b/tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr new file mode 100644 index 0000000000000..ed0a4b118d497 --- /dev/null +++ b/tests/ui/const-generics/const-param-type-depends-on-parent-param.stderr @@ -0,0 +1,9 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/const-param-type-depends-on-parent-param.rs:4:26 + | +LL | fn foo() {} + | ^ the type must not depend on the parameter `N` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr b/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr index 72d7001fdf1b0..c074e2e897e9a 100644 --- a/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr +++ b/tests/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr @@ -2,19 +2,19 @@ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/default-const-param-cannot-reference-self.rs:1:34 | LL | struct Struct; - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/default-const-param-cannot-reference-self.rs:4:30 | LL | enum Enum { } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/default-const-param-cannot-reference-self.rs:7:32 | LL | union Union { not_empty: () } - | ^^^^ `Self` in generic parameter default + | ^^^^ error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/defaults/forward-declared.rs b/tests/ui/const-generics/defaults/forward-declared.rs index ede3d873bdcf6..bd3abd4dcaa6a 100644 --- a/tests/ui/const-generics/defaults/forward-declared.rs +++ b/tests/ui/const-generics/defaults/forward-declared.rs @@ -1,13 +1,13 @@ struct Foo; -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared enum Bar {} -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared struct Foo2; -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared enum Bar2 {} -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared fn main() {} diff --git a/tests/ui/const-generics/defaults/forward-declared.stderr b/tests/ui/const-generics/defaults/forward-declared.stderr index 4856c7a1fd2d8..4331996bffcd9 100644 --- a/tests/ui/const-generics/defaults/forward-declared.stderr +++ b/tests/ui/const-generics/defaults/forward-declared.stderr @@ -1,26 +1,26 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/forward-declared.rs:1:29 | LL | struct Foo; - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `M` before it is declared -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/forward-declared.rs:4:27 | LL | enum Bar {} - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `M` before it is declared -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/forward-declared.rs:7:30 | LL | struct Foo2; - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `N` before it is declared -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/forward-declared.rs:10:28 | LL | enum Bar2 {} - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `N` before it is declared error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs index 91c1c80e07c88..2abf7f44e2030 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs +++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs @@ -4,8 +4,8 @@ use std::marker::PhantomData; struct UsesConst; -//~^ ERROR: the type of const parameters must not depend on other generic parameters +//~^ ERROR: const parameter types cannot reference parameters before they are declared struct UsesType(PhantomData); -//~^ ERROR: the type of const parameters must not depend on other generic parameters +//~^ ERROR: const parameter types cannot reference parameters before they are declared fn main() {} diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr index b0dbdff84136b..5526668b0be91 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr @@ -1,15 +1,14 @@ -error[E0770]: the type of const parameters must not depend on other generic parameters +error: const parameter types cannot reference parameters before they are declared --> $DIR/forward_declared_type.rs:6:32 | LL | struct UsesConst; - | ^ the type must not depend on the parameter `M` + | ^ const parameter type cannot reference `M` before it is declared -error[E0770]: the type of const parameters must not depend on other generic parameters +error: const parameter types cannot reference parameters before they are declared --> $DIR/forward_declared_type.rs:8:27 | LL | struct UsesType(PhantomData); - | ^ the type must not depend on the parameter `T` + | ^ const parameter type cannot reference `T` before it is declared error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr index 29171c8006afb..2d47797aef284 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr @@ -16,7 +16,7 @@ LL | type Assoc; = note: the only supported types are integers, `bool`, and `char` error: anonymous constants referencing generics are not yet supported - --> $DIR/references-parent-generics.rs:14:21 + --> $DIR/references-parent-generics.rs:15:21 | LL | let x: T::Assoc<3>; | ^ diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr index 64b413188144d..68ce17317f69f 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr @@ -1,16 +1,9 @@ -error: `Self` is forbidden as the type of a const generic parameter +error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/references-parent-generics.rs:7:25 | LL | type Assoc; - | ^^^^ - | - = note: the only supported types are integers, `bool`, and `char` - -error: anonymous constants referencing generics are not yet supported - --> $DIR/references-parent-generics.rs:14:21 - | -LL | let x: T::Assoc<3>; - | ^ + | ^^^^ the type must not depend on the parameter `Self` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs index 21994eb83b42c..b91050d540c90 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs +++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs @@ -5,14 +5,15 @@ trait Foo { type Assoc; - //~^ ERROR `Self` is forbidden as the type of a const generic parameter + //[nofeat]~^ ERROR the type of const parameters must not depend on other generic parameters + //[feat]~^^ ERROR `Self` is forbidden as the type of a const generic parameter } fn foo() { // We used to end up feeding the type of this anon const to be `T`, but the anon const // doesn't inherit the generics of `foo`, which led to index oob errors. let x: T::Assoc<3>; - //~^ ERROR anonymous constants referencing generics are not yet supported + //[feat]~^ ERROR anonymous constants referencing generics are not yet supported } fn main() {} diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr index 9f0b2efae96ce..dc28dea6851af 100644 --- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr +++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr @@ -4,11 +4,11 @@ error: generic parameters with a default must be trailing LL | struct Bar(T); | ^ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 | LL | struct Bar(T); - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `N` before it is declared error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr index 320c9c1c84de0..3f0e5e96fc814 100644 --- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr +++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr @@ -13,11 +13,11 @@ LL | struct Foo()]>(T, U); = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 | LL | struct Bar(T); - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `N` before it is declared error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs index 2794ff3eaa9cb..d212cc425a065 100644 --- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs +++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs @@ -6,7 +6,7 @@ struct Foo()]>(T, U); //[min]~^ ERROR generic parameters may not be used in const operations struct Bar(T); -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared //~| ERROR generic parameters with a default fn main() {} diff --git a/tests/ui/consts/const-unsized.stderr b/tests/ui/consts/const-unsized.stderr index 8328e19aac22d..cee364b33f7a0 100644 --- a/tests/ui/consts/const-unsized.stderr +++ b/tests/ui/consts/const-unsized.stderr @@ -58,18 +58,18 @@ error[E0507]: cannot move out of a shared reference LL | static STATIC_BAR: str = *"bar"; | ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait -error[E0161]: cannot move a value of type `str` - --> $DIR/const-unsized.rs:20:48 - | -LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); - | ^^^^^^^^^ the size of `str` cannot be statically determined - error[E0161]: cannot move a value of type `dyn Debug + Sync` --> $DIR/const-unsized.rs:20:38 | LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); | ^^^^^^^ the size of `dyn Debug + Sync` cannot be statically determined +error[E0161]: cannot move a value of type `str` + --> $DIR/const-unsized.rs:20:48 + | +LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); + | ^^^^^^^^^ the size of `str` cannot be statically determined + error: aborting due to 10 previous errors Some errors have detailed explanations: E0161, E0277, E0507. diff --git a/tests/ui/delegation/fn-header-variadic.rs b/tests/ui/delegation/fn-header-variadic.rs new file mode 100644 index 0000000000000..2c83d64d0b3ff --- /dev/null +++ b/tests/ui/delegation/fn-header-variadic.rs @@ -0,0 +1,25 @@ +//@ aux-crate:fn_header_aux=fn-header-aux.rs + +#![feature(c_variadic)] +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse { + pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} +} + +reuse to_reuse::variadic_fn; +//~^ ERROR delegation to C-variadic functions is not allowed +reuse fn_header_aux::variadic_fn_extern; +//~^ ERROR delegation to C-variadic functions is not allowed + +fn main() { + unsafe { + variadic_fn(0); + variadic_fn(0, 1); + variadic_fn_extern(0); + variadic_fn_extern(0, 1); + } + let _: unsafe extern "C" fn(usize, ...) = variadic_fn; + let _: unsafe extern "C" fn(usize, ...) = variadic_fn_extern; +} diff --git a/tests/ui/delegation/fn-header-variadic.stderr b/tests/ui/delegation/fn-header-variadic.stderr new file mode 100644 index 0000000000000..688a965fb4d5c --- /dev/null +++ b/tests/ui/delegation/fn-header-variadic.stderr @@ -0,0 +1,22 @@ +error: delegation to C-variadic functions is not allowed + --> $DIR/fn-header-variadic.rs:11:17 + | +LL | pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} + | ------------------------------------------------------------- callee defined here +... +LL | reuse to_reuse::variadic_fn; + | ^^^^^^^^^^^ + +error: delegation to C-variadic functions is not allowed + --> $DIR/fn-header-variadic.rs:13:22 + | +LL | reuse fn_header_aux::variadic_fn_extern; + | ^^^^^^^^^^^^^^^^^^ + | + ::: $DIR/auxiliary/fn-header-aux.rs:7:1 + | +LL | pub unsafe extern "C" fn variadic_fn_extern(n: usize, mut args: ...) {} + | -------------------------------------------------------------------- callee defined here + +error: aborting due to 2 previous errors + diff --git a/tests/ui/delegation/fn-header.rs b/tests/ui/delegation/fn-header.rs index db20e1058e061..9de0d549f20ac 100644 --- a/tests/ui/delegation/fn-header.rs +++ b/tests/ui/delegation/fn-header.rs @@ -10,20 +10,17 @@ mod to_reuse { pub unsafe fn unsafe_fn() {} pub extern "C" fn extern_fn() {} - pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} pub const fn const_fn() {} pub async fn async_fn() {} } reuse to_reuse::unsafe_fn; reuse to_reuse::extern_fn; -reuse to_reuse::variadic_fn; reuse to_reuse::const_fn; reuse to_reuse::async_fn; reuse fn_header_aux::unsafe_fn_extern; reuse fn_header_aux::extern_fn_extern; -reuse fn_header_aux::variadic_fn_extern; reuse fn_header_aux::const_fn_extern; reuse fn_header_aux::async_fn_extern; @@ -46,12 +43,4 @@ fn main() { extern_fn_extern(); let _: extern "C" fn() = extern_fn; let _: extern "C" fn() = extern_fn_extern; - unsafe { - variadic_fn(0); - variadic_fn(0, 1); - variadic_fn_extern(0); - variadic_fn_extern(0, 1); - } - let _: unsafe extern "C" fn(usize, ...) = variadic_fn; - let _: unsafe extern "C" fn(usize, ...) = variadic_fn_extern; } diff --git a/tests/ui/delegation/ice-issue-138362.rs b/tests/ui/delegation/ice-issue-138362.rs new file mode 100644 index 0000000000000..c30660098555b --- /dev/null +++ b/tests/ui/delegation/ice-issue-138362.rs @@ -0,0 +1,15 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait HasSelf { + fn method(self); +} +trait NoSelf { + fn method(); +} +impl NoSelf for u8 { + reuse HasSelf::method; + //~^ ERROR this function takes 1 argument but 0 arguments were supplied +} + +fn main() {} diff --git a/tests/ui/delegation/ice-issue-138362.stderr b/tests/ui/delegation/ice-issue-138362.stderr new file mode 100644 index 0000000000000..9feddc9feaec3 --- /dev/null +++ b/tests/ui/delegation/ice-issue-138362.stderr @@ -0,0 +1,19 @@ +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/ice-issue-138362.rs:11:20 + | +LL | reuse HasSelf::method; + | ^^^^^^ argument #1 is missing + | +note: method defined here + --> $DIR/ice-issue-138362.rs:5:8 + | +LL | fn method(self); + | ^^^^^^ ---- +help: provide the argument + | +LL | reuse HasSelf::method(/* value */); + | +++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/error-codes/E0128.stderr b/tests/ui/error-codes/E0128.stderr index c1ccb4c9e7440..22f1e200e29c2 100644 --- a/tests/ui/error-codes/E0128.stderr +++ b/tests/ui/error-codes/E0128.stderr @@ -1,8 +1,8 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/E0128.rs:1:14 | LL | struct Foo { - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `U` before it is declared error: aborting due to 1 previous error diff --git a/tests/ui/generics/generic-non-trailing-defaults.rs b/tests/ui/generics/generic-non-trailing-defaults.rs index 16ea71d48c825..ef500c420680f 100644 --- a/tests/ui/generics/generic-non-trailing-defaults.rs +++ b/tests/ui/generics/generic-non-trailing-defaults.rs @@ -5,6 +5,6 @@ struct Vec(A, T); struct Foo, C>(A, B, C); //~^ ERROR generic parameters with a default must be trailing -//~| ERROR generic parameters with a default cannot use +//~| ERROR generic parameter defaults cannot reference parameters before they are declared fn main() {} diff --git a/tests/ui/generics/generic-non-trailing-defaults.stderr b/tests/ui/generics/generic-non-trailing-defaults.stderr index 713ba091b861c..d9057e932f5fa 100644 --- a/tests/ui/generics/generic-non-trailing-defaults.stderr +++ b/tests/ui/generics/generic-non-trailing-defaults.stderr @@ -10,11 +10,11 @@ error: generic parameters with a default must be trailing LL | struct Foo, C>(A, B, C); | ^ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/generic-non-trailing-defaults.rs:6:23 | LL | struct Foo, C>(A, B, C); - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `C` before it is declared error: aborting due to 3 previous errors diff --git a/tests/ui/generics/generic-type-params-forward-mention.rs b/tests/ui/generics/generic-type-params-forward-mention.rs index 000c47095d27c..4a8f76d34aa90 100644 --- a/tests/ui/generics/generic-type-params-forward-mention.rs +++ b/tests/ui/generics/generic-type-params-forward-mention.rs @@ -1,6 +1,6 @@ // Ensure that we get an error and not an ICE for this problematic case. struct Foo, U = bool>(T, U); -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared fn main() { let x: Foo; } diff --git a/tests/ui/generics/generic-type-params-forward-mention.stderr b/tests/ui/generics/generic-type-params-forward-mention.stderr index d7a6faa19410d..ecc2387b48be8 100644 --- a/tests/ui/generics/generic-type-params-forward-mention.stderr +++ b/tests/ui/generics/generic-type-params-forward-mention.stderr @@ -1,8 +1,8 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/generic-type-params-forward-mention.rs:2:23 | LL | struct Foo, U = bool>(T, U); - | ^ defaulted generic parameters cannot be forward declared + | ^ cannot reference `U` before it is declared error: aborting due to 1 previous error diff --git a/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr b/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr index f3a550801b9bd..f659a144deff2 100644 --- a/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr +++ b/tests/ui/generics/issue-61631-default-type-param-cannot-reference-self.stderr @@ -2,37 +2,37 @@ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:13:25 | LL | struct Snobound<'a, P = Self> { x: Option<&'a P> } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:16:23 | LL | enum Enobound<'a, P = Self> { A, B(Option<&'a P>) } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:19:24 | LL | union Unobound<'a, P = Self> { x: i32, y: Option<&'a P> } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:25:31 | LL | struct Ssized<'a, P: Sized = [Self]> { x: Option<&'a P> } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:28:29 | LL | enum Esized<'a, P: Sized = [Self]> { A, B(Option<&'a P>) } - | ^^^^ `Self` in generic parameter default + | ^^^^ error[E0735]: generic parameters cannot use `Self` in their defaults --> $DIR/issue-61631-default-type-param-cannot-reference-self.rs:31:30 | LL | union Usized<'a, P: Sized = [Self]> { x: i32, y: Option<&'a P> } - | ^^^^ `Self` in generic parameter default + | ^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/issues/issue-18183.stderr b/tests/ui/issues/issue-18183.stderr index 11015d75d9735..07fa4cdc7535c 100644 --- a/tests/ui/issues/issue-18183.stderr +++ b/tests/ui/issues/issue-18183.stderr @@ -1,8 +1,8 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/issue-18183.rs:1:20 | LL | pub struct Foo(Bar); - | ^^^ defaulted generic parameters cannot be forward declared + | ^^^ cannot reference `Bar` before it is declared error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-26812.rs b/tests/ui/issues/issue-26812.rs index e0723e016b381..8eb030a8ec94f 100644 --- a/tests/ui/issues/issue-26812.rs +++ b/tests/ui/issues/issue-26812.rs @@ -1,5 +1,5 @@ fn avg(_: T) {} -//~^ ERROR generic parameters with a default cannot use forward declared identifiers +//~^ ERROR generic parameter defaults cannot reference parameters before they are declared //~| ERROR defaults for type parameters //~| WARN previously accepted diff --git a/tests/ui/issues/issue-26812.stderr b/tests/ui/issues/issue-26812.stderr index 4a18b23fd8b13..bb60d67e2876e 100644 --- a/tests/ui/issues/issue-26812.stderr +++ b/tests/ui/issues/issue-26812.stderr @@ -1,8 +1,8 @@ -error[E0128]: generic parameters with a default cannot use forward declared identifiers +error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/issue-26812.rs:1:10 | LL | fn avg(_: T) {} - | ^^^^^^^ defaulted generic parameters cannot be forward declared + | ^^^^^^^ cannot reference `T` before it is declared error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions --> $DIR/issue-26812.rs:1:8 diff --git a/tests/ui/rmeta/rmeta_bin-pass.rs b/tests/ui/rmeta/rmeta_bin-pass.rs new file mode 100644 index 0000000000000..7de4f3ba96137 --- /dev/null +++ b/tests/ui/rmeta/rmeta_bin-pass.rs @@ -0,0 +1,14 @@ +//@ compile-flags: --emit=obj,metadata --crate-type=bin +//@ aux-build:rmeta-meta.rs +//@ no-prefer-dynamic +//@ build-pass + +// Check that building a metadata bin crate works with a dependent, metadata +// crate if linking is not requested. + +extern crate rmeta_meta; +use rmeta_meta::Foo; + +pub fn main() { + let _ = Foo { field: 42 }; +} diff --git a/tests/ui/rmeta/rmeta_bin.rs b/tests/ui/rmeta/rmeta_bin.rs new file mode 100644 index 0000000000000..c7d2050cd59f7 --- /dev/null +++ b/tests/ui/rmeta/rmeta_bin.rs @@ -0,0 +1,14 @@ +//@ build-fail +//@ compile-flags: --crate-type=bin +//@ aux-build:rmeta-meta.rs +//@ no-prefer-dynamic +//@ error-pattern: crate `rmeta_meta` required to be available in rlib format, but was not found + +// Check that building a bin crate fails if a dependent crate is metadata-only. + +extern crate rmeta_meta; +use rmeta_meta::Foo; + +fn main() { + let _ = Foo { field: 42 }; +} diff --git a/tests/ui/rmeta/rmeta_bin.stderr b/tests/ui/rmeta/rmeta_bin.stderr new file mode 100644 index 0000000000000..830169e032a1b --- /dev/null +++ b/tests/ui/rmeta/rmeta_bin.stderr @@ -0,0 +1,4 @@ +error: crate `rmeta_meta` required to be available in rlib format, but was not found in this form + +error: aborting due to 1 previous error + diff --git a/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs index f3f9ce0bd879e..3a574af9bba7e 100644 --- a/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs +++ b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs @@ -26,14 +26,7 @@ extern "C" fn main(argc: core::ffi::c_int, argv: *const *const u8) -> core::ffi: let actual = unsafe { let mut actual: libc::sigaction = core::mem::zeroed(); libc::sigaction(libc::SIGPIPE, core::ptr::null(), &mut actual); - #[cfg(not(target_os = "aix"))] - { - actual.sa_sigaction - } - #[cfg(target_os = "aix")] - { - actual.sa_union.__su_sigaction as libc::sighandler_t - } + actual.sa_sigaction }; assert_eq!(actual, expected, "actual and expected SIGPIPE disposition in child differs"); diff --git a/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs index d16a2b4d8c8ab..3d93d50ca3fbb 100644 --- a/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs +++ b/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs @@ -20,14 +20,7 @@ pub fn assert_sigpipe_handler(expected_handler: SignalHandler) { let actual = unsafe { let mut actual: libc::sigaction = std::mem::zeroed(); libc::sigaction(libc::SIGPIPE, std::ptr::null(), &mut actual); - #[cfg(not(target_os = "aix"))] - { - actual.sa_sigaction - } - #[cfg(target_os = "aix")] - { - actual.sa_union.__su_sigaction as libc::sighandler_t - } + actual.sa_sigaction }; let expected = match expected_handler { diff --git a/tests/ui/runtime/signal-alternate-stack-cleanup.rs b/tests/ui/runtime/signal-alternate-stack-cleanup.rs index 8fce092827318..f2af86be0a5f5 100644 --- a/tests/ui/runtime/signal-alternate-stack-cleanup.rs +++ b/tests/ui/runtime/signal-alternate-stack-cleanup.rs @@ -29,14 +29,7 @@ fn main() { // Install signal handler that runs on alternate signal stack. let mut action: sigaction = std::mem::zeroed(); action.sa_flags = (SA_ONSTACK | SA_SIGINFO) as _; - #[cfg(not(target_os = "aix"))] - { - action.sa_sigaction = signal_handler as sighandler_t; - } - #[cfg(target_os = "aix")] - { - action.sa_union.__su_sigaction = signal_handler as sighandler_t; - } + action.sa_sigaction = signal_handler as sighandler_t; sigaction(SIGWINCH, &action, std::ptr::null_mut()); // Send SIGWINCH on exit. diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr index 55a5e4cd4971f..0fca91fd2f2f6 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -7,12 +7,12 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:22:18 + --> $DIR/type-checking-test-4.rs:22:13 | LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'a, 'static>; // Error - | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static` error: lifetime may not live long enough --> $DIR/type-checking-test-4.rs:28:5