diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index b39a33aff097e..630281bb09254 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -338,6 +338,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' { "invalid drop function pointer in vtable (not pointing to a function)" }, err_ub!(InvalidVtableDropFn(..)) => { "invalid drop function pointer in vtable (function has incompatible signature)" }, + // Stacked Borrows errors can happen here, see https://github.com/rust-lang/miri/issues/2123. + // (We assume there are no other MachineStop errors possible here.) + InterpError::MachineStop(_) => + { "vtable pointer does not have permission to read drop function pointer" }, ); try_validation!( self.ecx.read_size_and_align_from_vtable(vtable), @@ -347,6 +351,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' err_ub!(InvalidVtableAlignment(msg)) => { "invalid vtable: alignment {}", msg }, err_unsup!(ReadPointerAsBytes) => { "invalid size or align in vtable" }, + // Stacked Borrows errors can happen here, see https://github.com/rust-lang/miri/issues/2123. + // (We assume there are no other MachineStop errors possible here.) + InterpError::MachineStop(_) => + { "vtable pointer does not have permission to read size and alignment" }, ); // FIXME: More checks for the vtable. } diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 207d2870c5c79..4c734b1589b85 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -304,11 +304,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { error_code: TypeAnnotationNeeded, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let error_code = error_code.into(); - let mut err = self.tcx.sess.struct_span_err_with_code( - span, - &format!("type annotations needed"), - error_code, - ); + let mut err = + self.tcx.sess.struct_span_err_with_code(span, "type annotations needed", error_code); err.span_label(span, arg_data.cannot_infer_msg()); err } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index f2cfbea207e5d..3747fb5eca0cc 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -789,6 +789,7 @@ fn test_debugging_options_tracking_hash() { tracked!(thinlto, Some(true)); tracked!(thir_unsafeck, true); tracked!(tls_model, Some(TlsModel::GeneralDynamic)); + tracked!(translate_remapped_path_to_local_path, false); tracked!(trap_unreachable, Some(false)); tracked!(treat_err_as_bug, NonZeroUsize::new(1)); tracked!(tune_cpu, Some(String::from("abc"))); diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 775ebb48402aa..07d7a75522e0d 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1486,6 +1486,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .filter(|_| { // Only spend time on further checks if we have what to translate *to*. sess.opts.real_rust_source_base_dir.is_some() + // Some tests need the translation to be always skipped. + && sess.opts.debugging_opts.translate_remapped_path_to_local_path }) .filter(|virtual_dir| { // Don't translate away `/rustc/$hash` if we're still remapping to it, diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index c3b79917dda91..120d09ee35382 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -191,6 +191,20 @@ pub enum StmtKind<'tcx> { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] rustc_data_structures::static_assert_size!(Expr<'_>, 104); +#[derive( + Clone, + Debug, + Copy, + PartialEq, + Eq, + Hash, + HashStable, + TyEncodable, + TyDecodable, + TypeFoldable +)] +pub struct LocalVarId(pub hir::HirId); + /// A THIR expression. #[derive(Clone, Debug, HashStable)] pub struct Expr<'tcx> { @@ -332,7 +346,7 @@ pub enum ExprKind<'tcx> { }, /// A local variable. VarRef { - id: hir::HirId, + id: LocalVarId, }, /// Used to represent upvars mentioned in a closure/generator UpvarRef { @@ -340,7 +354,7 @@ pub enum ExprKind<'tcx> { closure_def_id: DefId, /// HirId of the root variable - var_hir_id: hir::HirId, + var_hir_id: LocalVarId, }, /// A borrow, e.g. `&arg`. Borrow { @@ -596,7 +610,7 @@ pub enum PatKind<'tcx> { mutability: Mutability, name: Symbol, mode: BindingMode, - var: hir::HirId, + var: LocalVarId, ty: Ty<'tcx>, subpattern: Option>, /// Is this the leftmost occurrence of the binding, i.e., is `var` the diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 981441fab040f..e77f5931dd65d 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -3,8 +3,7 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; -use rustc_hir::def_id::DefId; -use rustc_hir::HirId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::hir::place::Projection as HirProjection; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; @@ -57,7 +56,7 @@ pub(crate) enum PlaceBase { /// figure out that it is captured until all the `Field` projections are applied. Upvar { /// HirId of the upvar - var_hir_id: HirId, + var_hir_id: LocalVarId, /// DefId of the closure closure_def_id: DefId, /// The trait closure implements, `Fn`, `FnMut`, `FnOnce` @@ -151,12 +150,12 @@ fn is_ancestor_or_same_capture( /// `ty::MinCaptureList` of the root variable `var_hir_id`. fn compute_capture_idx<'tcx>( closure_min_captures: &ty::RootVariableMinCaptureList<'tcx>, - var_hir_id: HirId, + var_hir_id: LocalVarId, root_var_idx: usize, ) -> usize { let mut res = 0; for (var_id, capture_list) in closure_min_captures { - if *var_id == var_hir_id { + if *var_id == var_hir_id.0 { res += root_var_idx; break; } else { @@ -176,12 +175,12 @@ fn compute_capture_idx<'tcx>( /// Returns None, when the ancestor is not found. fn find_capture_matching_projections<'a, 'tcx>( typeck_results: &'a ty::TypeckResults<'tcx>, - var_hir_id: HirId, + var_hir_id: LocalVarId, closure_def_id: DefId, projections: &[PlaceElem<'tcx>], ) -> Option<(usize, &'a ty::CapturedPlace<'tcx>)> { let closure_min_captures = typeck_results.closure_min_captures.get(&closure_def_id)?; - let root_variable_min_captures = closure_min_captures.get(&var_hir_id)?; + let root_variable_min_captures = closure_min_captures.get(&var_hir_id.0)?; let hir_projections = convert_to_hir_projections_and_truncate_for_capture(projections); @@ -500,8 +499,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, ), ExprKind::UpvarRef { closure_def_id, var_hir_id } => { - let upvar_id = ty::UpvarId::new(var_hir_id, closure_def_id.expect_local()); - this.lower_captured_upvar(block, upvar_id) + this.lower_captured_upvar(block, closure_def_id.expect_local(), var_hir_id) } ExprKind::VarRef { id } => { @@ -627,11 +625,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn lower_captured_upvar( &mut self, block: BasicBlock, - upvar_id: ty::UpvarId, + closure_expr_id: LocalDefId, + var_hir_id: LocalVarId, ) -> BlockAnd> { - let closure_ty = self - .typeck_results - .node_type(self.tcx.hir().local_def_id_to_hir_id(upvar_id.closure_expr_id)); + let closure_ty = + self.typeck_results.node_type(self.tcx.hir().local_def_id_to_hir_id(closure_expr_id)); let closure_kind = if let ty::Closure(_, closure_substs) = closure_ty.kind() { self.infcx.closure_kind(closure_substs).unwrap() @@ -641,8 +639,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; block.and(PlaceBuilder::from(PlaceBase::Upvar { - var_hir_id: upvar_id.var_path.hir_id, - closure_def_id: upvar_id.closure_expr_id.to_def_id(), + var_hir_id, + closure_def_id: closure_expr_id.to_def_id(), closure_kind, })) } diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 43a84f69699aa..dc1860cb11297 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -14,7 +14,6 @@ use rustc_data_structures::{ fx::{FxHashSet, FxIndexMap, FxIndexSet}, stack::ensure_sufficient_stack, }; -use rustc_hir::HirId; use rustc_index::bit_set::BitSet; use rustc_middle::middle::region; use rustc_middle::mir::*; @@ -690,7 +689,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub(crate) fn storage_live_binding( &mut self, block: BasicBlock, - var: HirId, + var: LocalVarId, span: Span, for_guard: ForGuard, schedule_drop: bool, @@ -700,7 +699,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) }); // Altough there is almost always scope for given variable in corner cases // like #92893 we might get variable with no scope. - if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) && schedule_drop{ + if let Some(region_scope) = self.region_scope_tree.var_scope(var.0.local_id) && schedule_drop{ self.schedule_drop(span, region_scope, local_id, DropKind::Storage); } Place::from(local_id) @@ -708,12 +707,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub(crate) fn schedule_drop_for_binding( &mut self, - var: HirId, + var: LocalVarId, span: Span, for_guard: ForGuard, ) { let local_id = self.var_local_id(var, for_guard); - if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) { + if let Some(region_scope) = self.region_scope_tree.var_scope(var.0.local_id) { self.schedule_drop(span, region_scope, local_id, DropKind::Value); } } @@ -730,7 +729,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Mutability, Symbol, BindingMode, - HirId, + LocalVarId, Span, Ty<'tcx>, UserTypeProjections, @@ -917,7 +916,7 @@ fn traverse_candidate<'pat, 'tcx: 'pat, C, T, I>( struct Binding<'tcx> { span: Span, source: Place<'tcx>, - var_id: HirId, + var_id: LocalVarId, binding_mode: BindingMode, } @@ -2184,7 +2183,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mutability: Mutability, name: Symbol, mode: BindingMode, - var_id: HirId, + var_id: LocalVarId, var_ty: Ty<'tcx>, user_ty: UserTypeProjections, has_guard: ArmHasGuard, diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 4ae74433df63d..793066e43c3c7 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -4,11 +4,12 @@ use crate::build::scope::DropKind; use crate::thir::constant::parse_float; use crate::thir::pattern::pat_from_hir; use rustc_ast as ast; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; -use rustc_hir::{GeneratorKind, HirIdMap, Node}; +use rustc_hir::{GeneratorKind, Node}; use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; @@ -16,7 +17,7 @@ use rustc_middle::middle::region; use rustc_middle::mir::interpret::Allocation; use rustc_middle::mir::interpret::{ConstValue, LitToConstError, LitToConstInput, Scalar}; use rustc_middle::mir::*; -use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, PatKind, Thir}; +use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, PatKind, Thir}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeckResults}; use rustc_span::symbol::sym; @@ -445,7 +446,7 @@ struct Builder<'a, 'tcx> { /// Maps `HirId`s of variable bindings to the `Local`s created for them. /// (A match binding can have two locals; the 2nd is for the arm's guard.) - var_indices: HirIdMap, + var_indices: FxHashMap, local_decls: IndexVec>, canonical_user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>, upvar_mutbls: Vec, @@ -455,11 +456,11 @@ struct Builder<'a, 'tcx> { } impl<'a, 'tcx> Builder<'a, 'tcx> { - fn is_bound_var_in_guard(&self, id: hir::HirId) -> bool { + fn is_bound_var_in_guard(&self, id: LocalVarId) -> bool { self.guard_context.iter().any(|frame| frame.locals.iter().any(|local| local.id == id)) } - fn var_local_id(&self, id: hir::HirId, for_guard: ForGuard) -> Local { + fn var_local_id(&self, id: LocalVarId, for_guard: ForGuard) -> Local { self.var_indices[&id].local_id(for_guard) } } @@ -543,11 +544,11 @@ enum LocalsForNode { #[derive(Debug)] struct GuardFrameLocal { - id: hir::HirId, + id: LocalVarId, } impl GuardFrameLocal { - fn new(id: hir::HirId, _binding_mode: BindingMode) -> Self { + fn new(id: LocalVarId, _binding_mode: BindingMode) -> Self { GuardFrameLocal { id } } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index bd9f599fff0a1..fb2f5861c6f03 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -903,9 +903,12 @@ impl<'tcx> Cx<'tcx> { ); if is_upvar { - ExprKind::UpvarRef { closure_def_id: self.body_owner, var_hir_id } + ExprKind::UpvarRef { + closure_def_id: self.body_owner, + var_hir_id: LocalVarId(var_hir_id), + } } else { - ExprKind::VarRef { id: var_hir_id } + ExprKind::VarRef { id: LocalVarId(var_hir_id) } } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index e0dec1daf63c8..417cf0f89c412 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -19,7 +19,7 @@ use rustc_middle::mir::interpret::{get_slice_bytes, ConstValue}; use rustc_middle::mir::interpret::{ErrorHandled, LitToConstError, LitToConstInput}; use rustc_middle::mir::{self, UserTypeProjection}; use rustc_middle::mir::{BorrowKind, Field, Mutability}; -use rustc_middle::thir::{Ascription, BindingMode, FieldPat, Pat, PatKind, PatRange}; +use rustc_middle::thir::{Ascription, BindingMode, FieldPat, LocalVarId, Pat, PatKind, PatRange}; use rustc_middle::ty::subst::{GenericArg, SubstsRef}; use rustc_middle::ty::CanonicalUserTypeAnnotation; use rustc_middle::ty::{self, AdtDef, ConstKind, DefIdTree, Region, Ty, TyCtxt, UserType}; @@ -288,7 +288,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { mutability, mode, name: ident.name, - var: id, + var: LocalVarId(id), ty: var_ty, subpattern: self.lower_opt_pattern(sub), is_primary: id == pat.hir_id, @@ -664,7 +664,7 @@ macro_rules! ClonePatternFoldableImpls { } ClonePatternFoldableImpls! { <'tcx> - Span, Field, Mutability, Symbol, hir::HirId, usize, ty::Const<'tcx>, + Span, Field, Mutability, Symbol, LocalVarId, usize, ty::Const<'tcx>, Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>, SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>, UserTypeProjection, CanonicalUserTypeAnnotation<'tcx> diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d89c61c2e44c6..007fa87189fb0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1541,6 +1541,8 @@ options! { "choose the TLS model to use (`rustc --print tls-models` for details)"), trace_macros: bool = (false, parse_bool, [UNTRACKED], "for every macro invocation, print its name and arguments (default: no)"), + translate_remapped_path_to_local_path: bool = (true, parse_bool, [TRACKED], + "translate remapped paths into local paths when possible (default: yes)"), trap_unreachable: Option = (None, parse_opt_bool, [TRACKED], "generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)"), treat_err_as_bug: Option = (None, parse_treat_err_as_bug, [TRACKED], diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 5eda860264c6c..866419ac34b11 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -94,7 +94,7 @@ //! functions for requesting data from an object which implements `Provider`. Generally, end users //! should not call `request_*` directly, they are helper functions for intermediate implementers //! to use to implement a user-facing interface. This is purely for the sake of ergonomics, there is -//! safety concern here; intermediate implementers can typically support methods rather than +//! no safety concern here; intermediate implementers can typically support methods rather than //! free functions and use more specific names. //! //! Typically, a data provider is a trait object of a trait which extends `Provider`. A user will @@ -1007,7 +1007,7 @@ mod tags { type Reified = T; } - /// Type-based tag similar to [`Value`] but which may be unsized (i.e., has a `'Sized` bound). + /// Type-based tag similar to [`Value`] but which may be unsized (i.e., has a `?Sized` bound). #[derive(Debug)] pub struct MaybeSizedValue(PhantomData); diff --git a/src/test/ui/span/issue-71363.rs b/src/test/ui/span/issue-71363.rs index 3e85559caf923..bbb4a93623b14 100644 --- a/src/test/ui/span/issue-71363.rs +++ b/src/test/ui/span/issue-71363.rs @@ -1,6 +1,4 @@ -// compile-flags: -Z simulate-remapped-rust-src-base=/rustc/xyz -Z ui-testing=no -// only-x86_64-unknown-linux-gnu -//---^ Limiting target as the above unstable flags don't play well on some environment. +// compile-flags: -Z simulate-remapped-rust-src-base=/rustc/xyz -Z translate-remapped-path-to-local-path=no -Z ui-testing=no struct MyError; impl std::error::Error for MyError {} @@ -8,3 +6,14 @@ impl std::error::Error for MyError {} //~| ERROR: `MyError` doesn't implement `Debug` fn main() {} + +// This test relies on library/std/src/error.rs *not* being included in the error message, so that +// we can test whether a file not included in the error message affects it (more specifically +// whether the line number of the excluded file affects the indentation of the other line numbers). +// +// To test this we're simulating a remap of the rust src base (so that library/std/src/error.rs +// does not point to a local file) *and* we're disabling the code to try mapping a remapped path to +// a local file (which would defeat the purpose of the former flag). +// +// Note that this comment is at the bottom of the file intentionally, as we need the line number of +// the impl to be lower than 10. diff --git a/src/test/ui/span/issue-71363.stderr b/src/test/ui/span/issue-71363.stderr index d54f21752b89a..04e2b46c31738 100644 --- a/src/test/ui/span/issue-71363.stderr +++ b/src/test/ui/span/issue-71363.stderr @@ -1,7 +1,7 @@ error[E0277]: `MyError` doesn't implement `std::fmt::Display` - --> $DIR/issue-71363.rs:6:6 + --> $DIR/issue-71363.rs:4:6 | -6 | impl std::error::Error for MyError {} +4 | impl std::error::Error for MyError {} | ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `MyError` @@ -9,9 +9,9 @@ error[E0277]: `MyError` doesn't implement `std::fmt::Display` note: required by a bound in `std::error::Error` error[E0277]: `MyError` doesn't implement `Debug` - --> $DIR/issue-71363.rs:6:6 + --> $DIR/issue-71363.rs:4:6 | -6 | impl std::error::Error for MyError {} +4 | impl std::error::Error for MyError {} | ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `MyError` @@ -19,7 +19,7 @@ error[E0277]: `MyError` doesn't implement `Debug` note: required by a bound in `std::error::Error` help: consider annotating `MyError` with `#[derive(Debug)]` | -5 | #[derive(Debug)] +3 | #[derive(Debug)] | error: aborting due to 2 previous errors