diff options
Diffstat (limited to 'compiler')
87 files changed, 1133 insertions, 1205 deletions
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 571172be4ed..946f2cafa15 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_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index d1f238331d5..208d510db2e 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 145137f9236..3951b467961 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 876b8f214b0..7192a889adc 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 a15f9744bf3..412aaf70c3f 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 191c0444c74..693d22abbe6 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/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 9d5022f2bef..d2eb7a52f78 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,370 +209,6 @@ 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<Promoted, Body<'tcx>>, - last_span: Span, -} - -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; - } - } - - 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.typeck.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.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") - } - } - } - - #[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.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); - }); - - 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, - ); - } - } 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); - } - } - - 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, - ); - - 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, - ); - } - } - } - - fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { - self.super_local_decl(local, local_decl); - - 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; - - 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); - }; - - 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(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. - - for (local, local_decl) in body.local_decls.iter_enumerated() { - self.visit_local_decl(local, local_decl); - } - - 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; - } - - self.visit_terminator(block_data.terminator(), location); - } - } -} - -impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { - fn body(&self) -> &Body<'tcx> { - self.typeck.body - } - - fn tcx(&self) -> TyCtxt<'tcx> { - self.typeck.infcx.tcx - } - - fn verify_promoted(&mut self, promoted_body: &'b 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); - - // Use new sets of constraints and closure bounds so that we can - // modify their locations. - let polonius_facts = &mut None; - 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 - - 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); - }; - - swap_constraints(self); - - self.visit_body(promoted_body); - - self.typeck.typeck_mir(); - - 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; - constraint.locations = locations; - if let ConstraintCategory::Return(_) - | ConstraintCategory::UseAsConst - | ConstraintCategory::UseAsStatic = constraint.category - { - // "Returning" from a promoted is an assignment to a - // temporary from the user's point of view. - constraint.category = ConstraintCategory::Boring; - } - self.typeck.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 - // at the location provided as an argument to this method - // - // add_location doesn't care about ordering so not a problem for the live regions to be - // unordered. - #[allow(rustc::potential_query_instability)] - for region in liveness_constraints.live_regions_unordered() { - self.typeck.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 @@ -584,6 +217,9 @@ 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<Promoted, 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>, @@ -732,6 +368,10 @@ impl Locations { } impl<'a, 'tcx> TypeChecker<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + fn body(&self) -> &Body<'tcx> { self.body } @@ -859,6 +499,62 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Ok(()) } + 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.body, promoted_body); + + // Use new sets of constraints and closure bounds so that we can + // modify their locations. + let polonius_facts = &mut None; + 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 as they refer + // to the wrong locations. + let mut swap_constraints = |this: &mut Self| { + 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.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; + constraint.locations = locations; + if let ConstraintCategory::Return(_) + | ConstraintCategory::UseAsConst + | ConstraintCategory::UseAsStatic = constraint.category + { + // "Returning" from a promoted is an assignment to a + // temporary from the user's point of view. + constraint.category = ConstraintCategory::Boring; + } + 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 + // at the location provided as an argument to this method + // + // add_location doesn't care about ordering so not a problem for the live regions to be + // unordered. + #[allow(rustc::potential_query_instability)] + for region in liveness_constraints.live_regions_unordered() { + self.constraints.liveness_constraints.add_location(region, location); + } + } + fn check_inline_const( &mut self, inferred_ty: Ty<'tcx>, @@ -888,15 +584,40 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Locations::All(span), ); } +} - fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx +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; + } + } + + #[instrument(skip(self, body), level = "debug")] + fn visit_body(&mut self, body: &Body<'tcx>) { + debug_assert!(std::ptr::eq(self.body, body)); + + for (local, local_decl) in body.local_decls.iter_enumerated() { + self.visit_local_decl(local, local_decl); + } + + 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; + } + + self.visit_terminator(block_data.terminator(), location); + self.check_iscleanup(block_data); + } } #[instrument(skip(self), level = "debug")] - fn check_stmt(&mut self, stmt: &Statement<'tcx>, location: Location) { + fn visit_statement(&mut self, stmt: &Statement<'tcx>, location: Location) { + self.super_statement(stmt, location); let tcx = self.tcx(); - debug!("stmt kind: {:?}", stmt.kind); match &stmt.kind { StatementKind::Assign(box (place, rv)) => { // Assignments to temporaries are not "interesting"; @@ -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,385 +931,75 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - fn check_call_dest( - &mut self, - term: &Terminator<'tcx>, - sig: &ty::FnSig<'tcx>, - destination: Place<'tcx>, - target: Option<BasicBlock>, - 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<Operand<'tcx>>], - 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); + fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { + self.super_local_decl(local, local_decl); - 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()); + 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; - 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))) + 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 { - ConstraintCategory::Boring + bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty); }; - if let Err(terr) = - self.sub_types(op_arg_ty, *fn_arg, term_location.to_locations(), category) - { + + 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, - term, - "bad arg #{:?} ({:?} <- {:?}): {:?}", - n, - fn_arg, - op_arg_ty, - terr + local, + "bad user type on variable {:?}: {:?} != {:?} ({:?})", + local, + local_decl.ty, + local_decl.user_ty, + terr, ); } } - } - - 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); - } - } - - 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(_) => (), - } - } - - 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 => {} - } // 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); - } - } - - 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 }); - } - } - } - - fn aggregate_field_ty( - &mut self, - ak: &AggregateKind<'tcx>, - field_index: FieldIdx, - location: Location, - ) -> Result<Ty<'tcx>, 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() }) + 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; } - } - 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(), - ); - } + LocalKind::Temp => { + let span = local_decl.source_info.span; + let ty = local_decl.ty; + self.ensure_place_sized(ty, span); } } } } #[instrument(skip(self), level = "debug")] - fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { + 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) => { - for op in ops { - self.check_operand(op, location); - } - self.check_aggregate_rvalue(rvalue, ak, ops, location) - } + Rvalue::Aggregate(ak, ops) => 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())), @@ -1656,9 +1052,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &Rvalue::NullaryOp(NullOp::ContractChecks, _) => {} &Rvalue::NullaryOp(NullOp::UbChecks, _) => {} - Rvalue::ShallowInitBox(operand, ty) => { - self.check_operand(operand, location); - + Rvalue::ShallowInitBox(_operand, ty) => { let trait_ref = ty::TraitRef::new( tcx, tcx.require_lang_item(LangItem::Sized, Some(span)), @@ -1673,8 +1067,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } 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; @@ -2191,9 +1583,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { 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); - let ty_left = left.ty(self.body, tcx); match ty_left.kind() { // Types with regions are comparable if they have a common super-type. @@ -2242,23 +1631,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - Rvalue::Use(operand) | Rvalue::UnaryOp(_, operand) => { - self.check_operand(operand, location); - } - Rvalue::CopyForDeref(place) => { - let op = &Operand::Copy(*place); - self.check_operand(op, location); - } - - Rvalue::BinaryOp(_, box (left, right)) => { - self.check_operand(left, location); - self.check_operand(right, location); - } - 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!(); }; @@ -2276,7 +1650,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .unwrap(); } - Rvalue::RawPtr(..) + Rvalue::Use(_) + | Rvalue::UnaryOp(_, _) + | Rvalue::CopyForDeref(_) + | Rvalue::BinaryOp(..) + | Rvalue::RawPtr(..) | Rvalue::ThreadLocalRef(..) | Rvalue::Len(..) | Rvalue::Discriminant(..) @@ -2284,6 +1662,543 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } + #[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<BasicBlock>, + 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<Operand<'tcx>>], + 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); + } + } + + 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(_) => (), + } + } + + 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 }); + } + } + } + + fn aggregate_field_ty( + &mut self, + ak: &AggregateKind<'tcx>, + field_index: FieldIdx, + location: Location, + ) -> Result<Ty<'tcx>, 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"); + } + } + } + /// If this rvalue supports a user-given type annotation, then /// extract and return it. This represents the final type of the /// rvalue and will be unified with the inferred type. @@ -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_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 32f689608f8..3710625ac12 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 87992ce2e11..9cc737d194c 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<B: ExtraBackendMethods>( ) -> OngoingCodegen<B> { 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 63f2f8fa3d1..e9c886d28ed 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 27b8be1022e..998a4ff727e 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_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 607cb2e497d..06ee7075170 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_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 828a14e707c..16d70af7e05 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_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8dc5d361750..a266286664c 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 c193aad2afd..0a37a27b35b 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<Self>`, the // span points only at the type `Box<Self`>, 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<Span>) { 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<Span> = arg_spans(trait_.kind, trait_item.generics); let impl_trait_spans: Vec<Span> = 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<Span> = 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 a400aaa8142..fd5ffdc2d7a 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 750c09887a1..464ffa8711a 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 cee2f487639..c918abe4c07 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 dbf7a7378f5..0b7fc44460e 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 49523912b14..cfb6cf8a287 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<ty::ImplTraitHeader<'_>> { 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 4debd3977f5..7cbd31de6ba 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 6936544838c..16caa4f6874 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 4dbdfa3d85a..78b20f9897c 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 5f91f1d7b3e..8fff6eb9f6e 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_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 5e00161f693..2a24d626ac3 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 7e4026db738..7c6bb495be3 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 9ff7eeb2368..63e4a8fb44b 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 da2d6579423..c82f7a91168 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 35a3491f7c0..37aaaed5477 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/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index 69d7a6c97cb..72f8793d783 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 f87e5b5202a..ee01d78965d 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 cb1e89fb9e5..1a1540f505d 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 f570d0d8a0d..37f3786c00a 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 8f2ca6babea..1b2056f541f 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_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index 00600abb5f1..a2c1f1dbeda 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<LocalDefId> { 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_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f7be37dc4a2..918a42f3047 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 9ca148e1f25..4c2b82a9a23 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<Symbol>) { } 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 23d6efa0508..852bb01c096 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 4ede9b44087..aa6eef906ea 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<LintId> { #[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/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 49f9ad39780..722779d3268 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 fcadbfc3c4a..6f3c32af5ef 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_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 582c2215d92..be31aa629c8 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/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 88a88847e6b..57c941976e4 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 c85af81ee25..73c0af84a9f 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("<missing path>".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<DefId> { - 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<DefId> { + self.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id() } #[inline] - fn opt_ident(self, id: HirId) -> Option<Ident> { - match self.tcx.hir_node(id) { + fn hir_opt_ident(self, id: HirId) -> Option<Ident> { + 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<Span> { - self.opt_ident(id).map(|ident| ident.span) + pub(super) fn hir_opt_ident_span(self, id: HirId) -> Option<Span> { + 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<Symbol> { - self.opt_ident(id).map(|ident| ident.name) + pub fn hir_opt_name(self, id: HirId) -> Option<Symbol> { + 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<const N: usize = { ... }>` when /// called with the HirId for the `{ ... }` anon const pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option<LocalDefId> { @@ -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("<missing path>".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 6071a58367e..68b9a4f56b9 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/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f880b1364c2..573f7895da2 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 c8708857565..781a898a6e9 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 53f233f20eb..7e6151745e2 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 9ce5373b031..8e54a9d487d 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 5d9b1ddfa38..703b6ce9247 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 70bb902d1ae..a2472157d0e 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<LocalDefId> { - 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<ty::BoundVariableKind> { 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 97cfe5946af..ad9d32fd6c1 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<Item = &'tcx hir::Attribute> { 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<Item = &'tcx hir::Attribute> { 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 6c62c04f42e..f1d03d0a659 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 7d9c23c05f9..06054e22e76 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 f9fa750e750..2909dea98b7 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<Box<CoroutineInfo<'tcx>>>, ) -> 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 81561239491..27ff01b4803 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/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index e46e8c9871a..b8af77245f2 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 3d55c1401b6..b3daed8a7e0 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 dadd1e85461..cbd29ba837e 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_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c6ae2c0fb9b..ece5a53aaa9 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 7a14a7a5db2..7029c60c343 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 323b414cca0..e13d94c1031 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 25e679a8460..d2729876ebb 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<Span> { - 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 509c2f54775..84b92d49f24 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/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 822804893fe..ed70d9ee91f 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 8e59c0b3251..b06f16cc7bd 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 fd465717bf7..599a08bac20 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 0fcf6a80ec4..aea4386295f 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_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 91553700219..cf32f237b86 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -493,7 +493,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 +573,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 +597,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_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 9f062b3935f..817aa5b4385 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 88d1126de1a..41f4254eede 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<ast::NodeId>; @@ -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 b5d3e5ea776..2ae6892bc93 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 d9776be4dd0..5f0a2a597e9 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 2c3e4bb505c..d28988cd74f 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 f724ecf76b3..495ce843fcd 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -31,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; @@ -272,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. @@ -286,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<LabelSuggestion> }, /// Error E0323, E0324, E0325: mismatch between trait item and impl item. diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index acd3b758351..aa1921fc8e7 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_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 42d37418fb8..baf2489b2b8 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 a6d8eb6add7..40958ec1088 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 51b2a0b36bb..5583deda99a 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 fecb38ab597..c7f0a88f951 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 a7e68e6419d..cdbb92f4c7b 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 ad46a15a5ac..4f89f3c2b49 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<F>( &self, visitor: AwaitsVisitor, - hir: map::Map<'tcx>, + tcx: TyCtxt<'tcx>, ty_matches: F, ) -> Option<Span> 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_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index cc329ca3328..4a889abfc28 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_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index c84055f5b84..b7684e85d41 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<DefId> 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 6205578bf74..aeaa83c77b5 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<Item = Spa } fn impl_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span> { - 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 6dc5a9c4a47..90b3517eded 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/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index a107925fb18..3aad97d86cc 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 { |
