diff options
484 files changed, 8383 insertions, 4197 deletions
diff --git a/Cargo.lock b/Cargo.lock index 150a70341f5..37bbe95d633 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4168,6 +4168,7 @@ dependencies = [ name = "rustc_parse_format" version = "0.0.0" dependencies = [ + "rustc_data_structures", "rustc_lexer", ] @@ -4342,12 +4343,14 @@ dependencies = [ "rustc_feature", "rustc_fs_util", "rustc_hir", + "rustc_index", "rustc_lint_defs", "rustc_macros", "rustc_serialize", "rustc_span", "rustc_target", "smallvec", + "termize", "tracing", "winapi", ] @@ -4401,6 +4404,7 @@ dependencies = [ "rustc_span", "rustc_target", "tracing", + "twox-hash", ] [[package]] @@ -5392,6 +5396,17 @@ dependencies = [ ] [[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if 1.0.0", + "rand 0.8.5", + "static_assertions", +] + +[[package]] name = "type-map" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 07558ca075d..4fa18907fcd 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -259,6 +259,8 @@ enum ImplTraitContext { }, /// Impl trait in type aliases. TypeAliasesOpaqueTy, + /// `impl Trait` is unstably accepted in this position. + FeatureGated(ImplTraitPosition, Symbol), /// `impl Trait` is not accepted in this position. Disallowed(ImplTraitPosition), } @@ -1372,17 +1374,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } path } - ImplTraitContext::Disallowed( - position @ (ImplTraitPosition::TraitReturn | ImplTraitPosition::ImplReturn), - ) => { + ImplTraitContext::FeatureGated(position, feature) => { self.tcx .sess .create_feature_err( MisplacedImplTrait { span: t.span, - position: DiagnosticArgFromDisplay(&position), + position: DiagnosticArgFromDisplay(position), }, - sym::return_position_impl_trait_in_trait, + *feature, ) .emit(); hir::TyKind::Err @@ -1390,7 +1390,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::Disallowed(position) => { self.tcx.sess.emit_err(MisplacedImplTrait { span: t.span, - position: DiagnosticArgFromDisplay(&position), + position: DiagnosticArgFromDisplay(position), }); hir::TyKind::Err } @@ -1739,14 +1739,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { match &decl.output { FnRetTy::Ty(ty) => { - let mut context = if kind.return_impl_trait_allowed(self.tcx) { + let context = if kind.return_impl_trait_allowed(self.tcx) { let fn_def_id = self.local_def_id(fn_node_id); ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), in_trait: matches!(kind, FnDeclKind::Trait), } } else { - ImplTraitContext::Disallowed(match kind { + let position = match kind { FnDeclKind::Fn | FnDeclKind::Inherent => { unreachable!("fn should allow in-band lifetimes") } @@ -1755,9 +1755,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { FnDeclKind::Pointer => ImplTraitPosition::PointerReturn, FnDeclKind::Trait => ImplTraitPosition::TraitReturn, FnDeclKind::Impl => ImplTraitPosition::ImplReturn, - }) + }; + match kind { + FnDeclKind::Trait | FnDeclKind::Impl => ImplTraitContext::FeatureGated( + position, + sym::return_position_impl_trait_in_trait, + ), + _ => ImplTraitContext::Disallowed(position), + } }; - hir::FnRetTy::Return(self.lower_ty(ty, &mut context)) + hir::FnRetTy::Return(self.lower_ty(ty, &context)) } FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)), } @@ -1938,7 +1945,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { output, span, if in_trait && !this.tcx.features().return_position_impl_trait_in_trait { - ImplTraitContext::Disallowed(ImplTraitPosition::TraitReturn) + ImplTraitContext::FeatureGated( + ImplTraitPosition::TraitReturn, + sym::return_position_impl_trait_in_trait, + ) } else { ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 8d23c26e603..592fc5aa645 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -9,7 +9,7 @@ use rustc_ast::{self as ast, *}; use rustc_hir as hir; use rustc_hir::def::{DefKind, PartialRes, Res}; use rustc_hir::GenericArg; -use rustc_span::symbol::{kw, Ident}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; @@ -352,11 +352,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug // // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^ // ``` - FnRetTy::Ty(ty) - if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. }) - && self.tcx.features().impl_trait_in_fn_trait_return => - { - self.lower_ty(&ty, itctx) + FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. }) => { + if self.tcx.features().impl_trait_in_fn_trait_return { + self.lower_ty(&ty, itctx) + } else { + self.lower_ty( + &ty, + &ImplTraitContext::FeatureGated( + ImplTraitPosition::FnTraitReturn, + sym::impl_trait_in_fn_trait_return, + ), + ) + } } FnRetTy::Ty(ty) => { self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)) diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index f66a7ab3c03..6fd9290058c 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -106,7 +106,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.check_activations(location); match &terminator.kind { - TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => { + TerminatorKind::SwitchInt { discr, targets: _ } => { self.consume_operand(location, discr); } TerminatorKind::Drop { place: drop_place, target: _, unwind: _ } => { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 74b4e4a0cab..5289de9b0ab 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -644,7 +644,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx self.check_activations(loc, span, flow_state); match &term.kind { - TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => { + TerminatorKind::SwitchInt { discr, targets: _ } => { self.consume_operand(loc, (discr, span), flow_state); } TerminatorKind::Drop { place, target: _, unwind: _ } => { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6d4ec6b726e..814bc275019 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1360,25 +1360,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } } - TerminatorKind::SwitchInt { discr, switch_ty, .. } => { + TerminatorKind::SwitchInt { discr, .. } => { self.check_operand(discr, term_location); - let discr_ty = discr.ty(body, tcx); - if let Err(terr) = self.sub_types( - discr_ty, - *switch_ty, - term_location.to_locations(), - ConstraintCategory::Assignment, - ) { - span_mirbug!( - self, - term, - "bad SwitchInt ({:?} on {:?}): {:?}", - switch_ty, - discr_ty, - terr - ); - } + let switch_ty = discr.ty(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); } diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index e2d71825d55..9ae65c641fd 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -11,7 +11,7 @@ pub fn expand_concat( sp: rustc_span::Span, tts: TokenStream, ) -> Box<dyn base::MacResult + 'static> { - let Some(es) = base::get_exprs_from_tts(cx, sp, tts) else { + let Some(es) = base::get_exprs_from_tts(cx, tts) else { return DummyResult::any(sp); }; let mut accumulator = String::new(); diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index d1124145dcb..70ce5a6c419 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -137,7 +137,7 @@ pub fn expand_concat_bytes( sp: rustc_span::Span, tts: TokenStream, ) -> Box<dyn base::MacResult + 'static> { - let Some(es) = base::get_exprs_from_tts(cx, sp, tts) else { + let Some(es) = base::get_exprs_from_tts(cx, tts) else { return DummyResult::any(sp); }; let mut accumulator = Vec::new(); diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 0b4e545f7a3..a7283ea601b 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -52,7 +52,7 @@ pub fn expand_env<'cx>( sp: Span, tts: TokenStream, ) -> Box<dyn base::MacResult + 'cx> { - let mut exprs = match get_exprs_from_tts(cx, sp, tts) { + let mut exprs = match get_exprs_from_tts(cx, tts) { Some(exprs) if exprs.is_empty() => { cx.span_err(sp, "env! takes 1 or 2 arguments"); return DummyResult::any(sp); diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 8b07c110663..63bc0d552c1 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -333,7 +333,7 @@ pub fn make_format_args( parse::Piece::String(s) => { unfinished_literal.push_str(s); } - parse::Piece::NextArgument(parse::Argument { position, position_span, format }) => { + parse::Piece::NextArgument(box parse::Argument { position, position_span, format }) => { if !unfinished_literal.is_empty() { template.push(FormatArgsPiece::Literal(Symbol::intern(&unfinished_literal))); unfinished_literal.clear(); diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 1db44502742..06813d7ec95 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -372,8 +372,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } } - TerminatorKind::SwitchInt { discr, switch_ty, targets } => { - let discr = codegen_operand(fx, discr).load_scalar(fx); + TerminatorKind::SwitchInt { discr, targets } => { + let discr = codegen_operand(fx, discr); + let switch_ty = discr.layout().ty; + let discr = discr.load_scalar(fx); let use_bool_opt = switch_ty.kind() == fx.tcx.types.bool.kind() || (targets.iter().count() == 1 && targets.iter().next().unwrap().0 == 0); diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index bdf7318ce48..89a415cdb36 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/src/type_.rs @@ -300,4 +300,8 @@ impl<'gcc, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // Unsupported. self.context.new_rvalue_from_int(self.int_type, 0) } + + fn set_kcfi_type_metadata(&self, _function: RValue<'gcc>, _kcfi_typeid: u32) { + // Unsupported. + } } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index fed56cdd438..668d9292705 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -88,7 +88,8 @@ pub(crate) unsafe fn codegen( callee, args.as_ptr(), args.len() as c_uint, - None, + [].as_ptr(), + 0 as c_uint, ); llvm::LLVMSetTailCall(ret, True); if output.is_some() { @@ -132,8 +133,15 @@ pub(crate) unsafe fn codegen( .enumerate() .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint)) .collect::<Vec<_>>(); - let ret = - llvm::LLVMRustBuildCall(llbuilder, ty, callee, args.as_ptr(), args.len() as c_uint, None); + let ret = llvm::LLVMRustBuildCall( + llbuilder, + ty, + callee, + args.as_ptr(), + args.len() as c_uint, + [].as_ptr(), + 0 as c_uint, + ); llvm::LLVMSetTailCall(ret, True); llvm::LLVMBuildRetVoid(llbuilder); llvm::LLVMDisposeBuilder(llbuilder); diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 77dd15ef4d8..83bffb20e0c 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -20,6 +20,7 @@ use rustc_middle::ty::layout::{ }; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; +use rustc_symbol_mangling::typeid::kcfi_typeid_for_fnabi; use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange}; use rustc_target::spec::{HasTargetSpec, Target}; use std::borrow::Cow; @@ -225,9 +226,25 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { debug!("invoke {:?} with args ({:?})", llfn, args); let args = self.check_call("invoke", llty, llfn, args); - let bundle = funclet.map(|funclet| funclet.bundle()); - let bundle = bundle.as_ref().map(|b| &*b.raw); + let funclet_bundle = funclet.map(|funclet| funclet.bundle()); + let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw); + let mut bundles = vec![funclet_bundle]; + + // Set KCFI operand bundle + let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; + let kcfi_bundle = + if self.tcx.sess.is_sanitizer_kcfi_enabled() && fn_abi.is_some() && is_indirect_call { + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap()); + Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) + } else { + None + }; + if kcfi_bundle.is_some() { + let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw); + bundles.push(kcfi_bundle); + } + bundles.retain(|bundle| bundle.is_some()); let invoke = unsafe { llvm::LLVMRustBuildInvoke( self.llbuilder, @@ -237,7 +254,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { args.len() as c_uint, then, catch, - bundle, + bundles.as_ptr(), + bundles.len() as c_uint, UNNAMED, ) }; @@ -1143,7 +1161,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { llfn, args.as_ptr() as *const &llvm::Value, args.len() as c_uint, - None, + [].as_ptr(), + 0 as c_uint, ); } } @@ -1159,9 +1178,25 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { debug!("call {:?} with args ({:?})", llfn, args); let args = self.check_call("call", llty, llfn, args); - let bundle = funclet.map(|funclet| funclet.bundle()); - let bundle = bundle.as_ref().map(|b| &*b.raw); + let funclet_bundle = funclet.map(|funclet| funclet.bundle()); + let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw); + let mut bundles = vec![funclet_bundle]; + + // Set KCFI operand bundle + let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; + let kcfi_bundle = + if self.tcx.sess.is_sanitizer_kcfi_enabled() && fn_abi.is_some() && is_indirect_call { + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap()); + Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) + } else { + None + }; + if kcfi_bundle.is_some() { + let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw); + bundles.push(kcfi_bundle); + } + bundles.retain(|bundle| bundle.is_some()); let call = unsafe { llvm::LLVMRustBuildCall( self.llbuilder, @@ -1169,7 +1204,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { llfn, args.as_ptr() as *const &llvm::Value, args.len() as c_uint, - bundle, + bundles.as_ptr(), + bundles.len() as c_uint, ) }; if let Some(fn_abi) = fn_abi { diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 4dcc7cd5447..aa1735f38ac 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -250,6 +250,11 @@ pub unsafe fn create_module<'ll>( ); } + if sess.is_sanitizer_kcfi_enabled() { + let kcfi = "kcfi\0".as_ptr().cast(); + llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1); + } + // Control Flow Guard is currently only supported by the MSVC linker on Windows. if sess.target.is_like_msvc { match sess.opts.cg.control_flow_guard { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index d87117dffdc..a9e3dcf4cb3 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -27,9 +27,7 @@ use rustc_codegen_ssa::traits::*; use rustc_fs_util::path_to_c_string; use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::bug; -use rustc_middle::mir::{self, GeneratorLayout}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{ @@ -1026,33 +1024,6 @@ fn build_struct_type_di_node<'ll, 'tcx>( // Tuples //=----------------------------------------------------------------------------- -/// Returns names of captured upvars for closures and generators. -/// -/// Here are some examples: -/// - `name__field1__field2` when the upvar is captured by value. -/// - `_ref__name__field` when the upvar is captured by reference. -/// -/// For generators this only contains upvars that are shared by all states. -fn closure_saved_names_of_captured_variables(tcx: TyCtxt<'_>, def_id: DefId) -> SmallVec<String> { - let body = tcx.optimized_mir(def_id); - - body.var_debug_info - .iter() - .filter_map(|var| { - let is_ref = match var.value { - mir::VarDebugInfoContents::Place(place) if place.local == mir::Local::new(1) => { - // The projection is either `[.., Field, Deref]` or `[.., Field]`. It - // implies whether the variable is captured by value or by reference. - matches!(place.projection.last().unwrap(), mir::ProjectionElem::Deref) - } - _ => return None, - }; - let prefix = if is_ref { "_ref__" } else { "" }; - Some(prefix.to_owned() + var.name.as_str()) - }) - .collect() -} - /// Builds the DW_TAG_member debuginfo nodes for the upvars of a closure or generator. /// For a generator, this will handle upvars shared by all states. fn build_upvar_field_di_nodes<'ll, 'tcx>( @@ -1083,7 +1054,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>( .all(|&t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)) ); - let capture_names = closure_saved_names_of_captured_variables(cx.tcx, def_id); + let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let layout = cx.layout_of(closure_or_generator_ty); up_var_tys @@ -1229,43 +1200,6 @@ fn build_union_type_di_node<'ll, 'tcx>( ) } -// FIXME(eddyb) maybe precompute this? Right now it's computed once -// per generator monomorphization, but it doesn't depend on substs. -fn generator_layout_and_saved_local_names<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: DefId, -) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>) { - let body = tcx.optimized_mir(def_id); - let generator_layout = body.generator_layout().unwrap(); - let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys); - - let state_arg = mir::Local::new(1); - for var in &body.var_debug_info { - let mir::VarDebugInfoContents::Place(place) = &var.value else { continue }; - if place.local != state_arg { - continue; - } - match place.projection[..] { - [ - // Deref of the `Pin<&mut Self>` state argument. - mir::ProjectionElem::Field(..), - mir::ProjectionElem::Deref, - // Field of a variant of the state. - mir::ProjectionElem::Downcast(_, variant), - mir::ProjectionElem::Field(field, _), - ] => { - let name = &mut generator_saved_local_names - [generator_layout.variant_fields[variant][field]]; - if name.is_none() { - name.replace(var.name); - } - } - _ => {} - } - } - (generator_layout, generator_saved_local_names) -} - /// Computes the type parameters for a type, if any, for the given metadata. fn build_generic_type_param_di_nodes<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 53e8a291d1e..69443b9b828 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -22,9 +22,9 @@ use crate::{ common::CodegenCx, debuginfo::{ metadata::{ - build_field_di_node, closure_saved_names_of_captured_variables, + build_field_di_node, enums::{tag_base_type, DiscrResult}, - file_metadata, generator_layout_and_saved_local_names, size_and_align_of, type_di_node, + file_metadata, size_and_align_of, type_di_node, type_map::{self, Stub, UniqueTypeId}, unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA, UNKNOWN_LINE_NUMBER, @@ -677,9 +677,9 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>( }; let (generator_layout, state_specific_upvar_names) = - generator_layout_and_saved_local_names(cx.tcx, generator_def_id); + cx.tcx.generator_layout_and_saved_local_names(generator_def_id); - let common_upvar_names = closure_saved_names_of_captured_variables(cx.tcx, generator_def_id); + let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id); let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx); let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len(); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index becbccc434d..93419d27a62 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -4,9 +4,8 @@ use crate::{ common::CodegenCx, debuginfo::{ metadata::{ - closure_saved_names_of_captured_variables, enums::tag_base_type, - file_metadata, generator_layout_and_saved_local_names, size_and_align_of, type_di_node, + file_metadata, size_and_align_of, type_di_node, type_map::{self, Stub, StubInfo, UniqueTypeId}, unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, UNKNOWN_LINE_NUMBER, @@ -157,7 +156,7 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>( ), |cx, generator_type_di_node| { let (generator_layout, state_specific_upvar_names) = - generator_layout_and_saved_local_names(cx.tcx, generator_def_id); + cx.tcx.generator_layout_and_saved_local_names(generator_def_id); let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } = generator_type_and_layout.variants else { bug!( @@ -167,7 +166,7 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>( }; let common_upvar_names = - closure_saved_names_of_captured_variables(cx.tcx, generator_def_id); + cx.tcx.closure_saved_names_of_captured_variables(generator_def_id); // Build variant struct types let variant_struct_type_di_nodes: SmallVec<_> = variants diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index dc21a02cec4..6a575095f7e 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -20,7 +20,7 @@ use crate::type_::Type; use crate::value::Value; use rustc_codegen_ssa::traits::TypeMembershipMethods; use rustc_middle::ty::Ty; -use rustc_symbol_mangling::typeid::typeid_for_fnabi; +use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi}; use smallvec::SmallVec; /// Declare a function. @@ -136,6 +136,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { self.set_type_metadata(llfn, typeid); } + if self.tcx.sess.is_sanitizer_kcfi_enabled() { + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi); + self.set_kcfi_type_metadata(llfn, kcfi_typeid); + } + llfn } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8a9392255b8..e61dbe8b8fc 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -427,6 +427,7 @@ pub enum MetadataType { MD_type = 19, MD_vcall_visibility = 28, MD_noundef = 29, + MD_kcfi_type = 36, } /// LLVMRustAsmDialect @@ -1063,6 +1064,7 @@ extern "C" { pub fn LLVMGlobalSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata); pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata); pub fn LLVMValueAsMetadata(Node: &Value) -> &Metadata; + pub fn LLVMIsAFunction(Val: &Value) -> Option<&Value>; // Operations on constants of any type pub fn LLVMConstNull(Ty: &Type) -> &Value; @@ -1273,7 +1275,8 @@ extern "C" { NumArgs: c_uint, Then: &'a BasicBlock, Catch: &'a BasicBlock, - Bundle: Option<&OperandBundleDef<'a>>, + OpBundles: *const Option<&OperandBundleDef<'a>>, + NumOpBundles: c_uint, Name: *const c_char, ) -> &'a Value; pub fn LLVMBuildLandingPad<'a>( @@ -1643,7 +1646,8 @@ extern "C" { Fn: &'a Value, Args: *const &'a Value, NumArgs: c_uint, - Bundle: Option<&OperandBundleDef<'a>>, + OpBundles: *const Option<&OperandBundleDef<'a>>, + NumOpBundles: c_uint, ) -> &'a Value; pub fn LLVMRustBuildMemCpy<'a>( B: &Builder<'a>, diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 5772b7e1d81..ff111d96f84 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -316,4 +316,19 @@ impl<'ll, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'ll, 'tcx> { ) } } + + fn set_kcfi_type_metadata(&self, function: &'ll Value, kcfi_typeid: u32) { + let kcfi_type_metadata = self.const_u32(kcfi_typeid); + unsafe { + llvm::LLVMGlobalSetMetadata( + function, + llvm::MD_kcfi_type as c_uint, + llvm::LLVMMDNodeInContext2( + self.llcx, + &llvm::LLVMValueAsMetadata(kcfi_type_metadata), + 1, + ), + ) + } + } } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 540f15c89e9..882430694e1 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -102,7 +102,7 @@ pub fn link_binary<'a>( sess, crate_type, outputs, - codegen_results.crate_info.local_crate_name.as_str(), + codegen_results.crate_info.local_crate_name, ); match crate_type { CrateType::Rlib => { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 03d833fbba8..f3f5ddb52d6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -307,12 +307,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { helper: TerminatorCodegenHelper<'tcx>, bx: &mut Bx, discr: &mir::Operand<'tcx>, - switch_ty: Ty<'tcx>, targets: &SwitchTargets, ) { let discr = self.codegen_operand(bx, &discr); - // `switch_ty` is redundant, sanity-check that. - assert_eq!(discr.layout.ty, switch_ty); + let switch_ty = discr.layout.ty; let mut target_iter = targets.iter(); if target_iter.len() == 1 { // If there are two targets (one conditional, one fallback), emit `br` instead of @@ -1293,8 +1291,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { helper.funclet_br(self, bx, target, mergeable_succ()) } - mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref targets } => { - self.codegen_switchint_terminator(helper, bx, discr, switch_ty, targets); + mir::TerminatorKind::SwitchInt { ref discr, ref targets } => { + self.codegen_switchint_terminator(helper, bx, discr, targets); MergingSucc::False } diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 99283d3bb29..b7982b633f5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -3,12 +3,12 @@ use rustc_index::vec::IndexVec; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir; use rustc_middle::ty; +use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_session::config::DebugInfo; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, Span}; -use rustc_target::abi::Abi; -use rustc_target::abi::Size; +use rustc_target::abi::{Abi, Size, VariantIdx}; use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; @@ -76,6 +76,106 @@ impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> { } } +trait DebugInfoOffsetLocation<'tcx, Bx> { + fn deref(&self, bx: &mut Bx) -> Self; + fn layout(&self) -> TyAndLayout<'tcx>; + fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self; + fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self; +} + +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx> + for PlaceRef<'tcx, Bx::Value> +{ + fn deref(&self, bx: &mut Bx) -> Self { + bx.load_operand(*self).deref(bx.cx()) + } + + fn layout(&self) -> TyAndLayout<'tcx> { + self.layout + } + + fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self { + PlaceRef::project_field(*self, bx, field.index()) + } + + fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self { + self.project_downcast(bx, variant) + } +} + +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx> + for TyAndLayout<'tcx> +{ + fn deref(&self, bx: &mut Bx) -> Self { + bx.cx().layout_of( + self.ty.builtin_deref(true).unwrap_or_else(|| bug!("cannot deref `{}`", self.ty)).ty, + ) + } + + fn layout(&self) -> TyAndLayout<'tcx> { + *self + } + + fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self { + self.field(bx.cx(), field.index()) + } + + fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self { + self.for_variant(bx.cx(), variant) + } +} + +struct DebugInfoOffset<T> { + /// Offset from the `base` used to calculate the debuginfo offset. + direct_offset: Size, + /// Each offset in this vector indicates one level of indirection from the base or previous + /// indirect offset plus a dereference. + indirect_offsets: Vec<Size>, + /// The final location debuginfo should point to. + result: T, +} + +fn calculate_debuginfo_offset< + 'a, + 'tcx, + Bx: BuilderMethods<'a, 'tcx>, + L: DebugInfoOffsetLocation<'tcx, Bx>, +>( + bx: &mut Bx, + local: mir::Local, + var: &PerLocalVarDebugInfo<'tcx, Bx::DIVariable>, + base: L, +) -> DebugInfoOffset<L> { + let mut direct_offset = Size::ZERO; + // FIXME(eddyb) use smallvec here. + let mut indirect_offsets = vec![]; + let mut place = base; + + for elem in &var.projection[..] { + match *elem { + mir::ProjectionElem::Deref => { + indirect_offsets.push(Size::ZERO); + place = place.deref(bx); + } + mir::ProjectionElem::Field(field, _) => { + let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset); + *offset += place.layout().fields.offset(field.index()); + place = place.project_field(bx, field); + } + mir::ProjectionElem::Downcast(_, variant) => { + place = place.downcast(bx, variant); + } + _ => span_bug!( + var.source_info.span, + "unsupported var debuginfo place `{:?}`", + mir::Place { local, projection: var.projection }, + ), + } + } + + DebugInfoOffset { direct_offset, indirect_offsets, result: place } +} + impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn set_debug_loc(&self, bx: &mut Bx, source_info: mir::SourceInfo) { bx.set_span(source_info.span); @@ -262,33 +362,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Some(dbg_var) = var.dbg_var else { continue }; let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue }; - let mut direct_offset = Size::ZERO; - // FIXME(eddyb) use smallvec here. - let mut indirect_offsets = vec![]; - let mut place = base; - - for elem in &var.projection[..] { - match *elem { - mir::ProjectionElem::Deref => { - indirect_offsets.push(Size::ZERO); - place = bx.load_operand(place).deref(bx.cx()); - } - mir::ProjectionElem::Field(field, _) => { - let i = field.index(); - let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset); - *offset += place.layout.fields.offset(i); - place = place.project_field(bx, i); - } - mir::ProjectionElem::Downcast(_, variant) => { - place = place.project_downcast(bx, variant); - } - _ => span_bug!( - var.source_info.span, - "unsupported var debuginfo place `{:?}`", - mir::Place { local, projection: var.projection }, - ), - } - } + let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } = + calculate_debuginfo_offset(bx, local, &var, base.layout); // When targeting MSVC, create extra allocas for arguments instead of pointing multiple // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records @@ -306,6 +381,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { || !matches!(&indirect_offsets[..], [Size::ZERO] | [])); if should_create_individual_allocas { + let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } = + calculate_debuginfo_offset(bx, local, &var, base); + // Create a variable which will be a pointer to the actual value let ptr_ty = bx.tcx().mk_ty(ty::RawPtr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 86481d5d758..109161ccc83 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -122,6 +122,7 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> { pub trait TypeMembershipMethods<'tcx>: Backend<'tcx> { fn set_type_metadata(&self, function: Self::Function, typeid: String); fn typeid_metadata(&self, typeid: String) -> Self::Value; + fn set_kcfi_type_metadata(&self, function: Self::Function, typeid: u32); } pub trait ArgAbiMethods<'tcx>: HasCodegen<'tcx> { diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index e3dfd72d5f0..c60d6e4fed9 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -123,14 +123,14 @@ impl<'tcx> ConstEvalErr<'tcx> { // Helper closure to print duplicated lines. let mut flush_last_line = |last_frame, times| { if let Some((line, span)) = last_frame { - err.span_label(span, &line); + err.span_note(span, &line); // Don't print [... additional calls ...] if the number of lines is small if times < 3 { for _ in 0..times { - err.span_label(span, &line); + err.span_note(span, &line); } } else { - err.span_label( + err.span_note( span, format!("[... {} additional calls {} ...]", times, &line), ); diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index e17d3e516a6..0b2809f1d2c 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::{ }; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_session::Limit; -use rustc_span::{Pos, Span}; +use rustc_span::Span; use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout}; use super::{ @@ -256,25 +256,13 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> { if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::ClosureExpr { - write!(f, "inside closure")?; + write!(f, "inside closure") } else { // Note: this triggers a `good_path_bug` state, which means that if we ever get here // we must emit a diagnostic. We should never display a `FrameInfo` unless we // actually want to emit a warning or error to the user. - write!(f, "inside `{}`", self.instance)?; + write!(f, "inside `{}`", self.instance) } - if !self.span.is_dummy() { - let sm = tcx.sess.source_map(); - let lo = sm.lookup_char_pos(self.span.lo()); - write!( - f, - " at {}:{}:{}", - sm.filename_for_diagnostics(&lo.file.name), - lo.line, - lo.col.to_usize() + 1 - )?; - } - Ok(()) }) } } diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 88d25be6bd8..0604d5ee6fa 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -373,9 +373,21 @@ pub trait Machine<'mir, 'tcx>: Sized { Ok(()) } - /// Executes a retagging operation. + /// Executes a retagging operation for a single pointer. + /// Returns the possibly adjusted pointer. #[inline] - fn retag( + fn retag_ptr_value( + _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _kind: mir::RetagKind, + val: &ImmTy<'tcx, Self::Provenance>, + ) -> InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> { + Ok(val.clone()) + } + + /// Executes a retagging operation on a compound value. + /// Replaces all pointers stored in the given place. + #[inline] + fn retag_place_contents( _ecx: &mut InterpCx<'mir, 'tcx, Self>, _kind: mir::RetagKind, _place: &PlaceTy<'tcx, Self::Provenance>, diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 60578246eed..81b44a49484 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -8,7 +8,7 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::ty::layout::LayoutOf; -use super::{InterpCx, Machine}; +use super::{ImmTy, InterpCx, Machine}; /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the /// same type as the result. @@ -108,7 +108,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Stacked Borrows. Retag(kind, place) => { let dest = self.eval_place(**place)?; - M::retag(self, *kind, &dest)?; + M::retag_place_contents(self, *kind, &dest)?; } Intrinsic(box ref intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?, @@ -247,10 +247,41 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_scalar(Scalar::from_machine_usize(len, self), &dest)?; } - AddressOf(_, place) | Ref(_, _, place) => { + Ref(_, borrow_kind, place) => { let src = self.eval_place(place)?; let place = self.force_allocation(&src)?; - self.write_immediate(place.to_ref(self), &dest)?; + let val = ImmTy::from_immediate(place.to_ref(self), dest.layout); + // A fresh reference was created, make sure it gets retagged. + let val = M::retag_ptr_value( + self, + if borrow_kind.allows_two_phase_borrow() { + mir::RetagKind::TwoPhase + } else { + mir::RetagKind::Default + }, + &val, + )?; + self.write_immediate(*val, &dest)?; + } + + AddressOf(_, place) => { + // Figure out whether this is an addr_of of an already raw place. + let place_base_raw = if place.has_deref() { + let ty = self.frame().body.local_decls[place.local].ty; + ty.is_unsafe_ptr() + } else { + // Not a deref, and thus not raw. + false + }; + + let src = self.eval_place(place)?; + let place = self.force_allocation(&src)?; + let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout); + if !place_base_raw { + // If this was not already raw, it needs retagging. + val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?; + } + self.write_immediate(*val, &dest)?; } NullaryOp(null_op, ty) => { diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 57e40e168fa..0e7ffcdffc9 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -29,10 +29,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Goto { target } => self.go_to_block(target), - SwitchInt { ref discr, ref targets, switch_ty } => { + SwitchInt { ref discr, ref targets } => { let discr = self.read_immediate(&self.eval_operand(discr, None)?)?; trace!("SwitchInt({:?})", *discr); - assert_eq!(discr.layout.ty, switch_ty); // Branch to the `otherwise` case by default, if no match is found. let mut target_block = targets.otherwise(); diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index bf700d31224..64318f5f54d 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_index::bit_set::BitSet; +use rustc_infer::traits::Reveal; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; use rustc_middle::mir::visit::{PlaceContext, Visitor}; @@ -44,8 +45,11 @@ impl<'tcx> MirPass<'tcx> for Validator { return; } let def_id = body.source.def_id(); - let param_env = tcx.param_env(def_id); let mir_phase = self.mir_phase; + let param_env = match mir_phase.reveal() { + Reveal::UserFacing => tcx.param_env(def_id), + Reveal::All => tcx.param_env_reveal_all_normalized(def_id), + }; let always_live_locals = always_storage_live_locals(body); let storage_liveness = MaybeStorageLive::new(always_live_locals) @@ -682,17 +686,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { TerminatorKind::Goto { target } => { self.check_edge(location, *target, EdgeKind::Normal); } - TerminatorKind::SwitchInt { targets, switch_ty, discr } => { - let ty = discr.ty(&self.body.local_decls, self.tcx); - if ty != *switch_ty { - self.fail( - location, - format!( - "encountered `SwitchInt` terminator with type mismatch: {:?} != {:?}", - ty, switch_ty, - ), - ); - } + TerminatorKind::SwitchInt { targets, discr } => { + let switch_ty = discr.ty(&self.body.local_decls, self.tcx); let target_width = self.tcx.sess.target.pointer_width; diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 22f87514dd8..f06ca5a0733 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -25,6 +25,7 @@ use rustc_data_structures::sync::SeqCst; use rustc_errors::registry::{InvalidErrorCode, Registry}; use rustc_errors::{ErrorGuaranteed, PResult}; use rustc_feature::find_gated_cfg; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; @@ -374,14 +375,14 @@ fn run_compiler( queries.global_ctxt()?.peek_mut().enter(|tcx| { let result = tcx.analysis(()); if sess.opts.unstable_opts.save_analysis { - let crate_name = queries.crate_name()?.peek().clone(); + let crate_name = tcx.crate_name(LOCAL_CRATE); sess.time("save_analysis", || { save::process_crate( tcx, - &crate_name, + crate_name, compiler.input(), None, - DumpHandler::new(compiler.output_dir().as_deref(), &crate_name), + DumpHandler::new(compiler.output_dir().as_deref(), crate_name), ) }); } @@ -678,7 +679,7 @@ fn print_crate_info( let crate_types = collect_crate_types(sess, attrs); for &style in &crate_types { let fname = - rustc_session::output::filename_for_input(sess, style, &id, &t_outputs); + rustc_session::output::filename_for_input(sess, style, id, &t_outputs); println!("{}", fname.file_name().unwrap().to_string_lossy()); } } diff --git a/compiler/rustc_error_messages/locales/en-US/expand.ftl b/compiler/rustc_error_messages/locales/en-US/expand.ftl index 5720591154f..df0e8ae5dd8 100644 --- a/compiler/rustc_error_messages/locales/en-US/expand.ftl +++ b/compiler/rustc_error_messages/locales/en-US/expand.ftl @@ -20,3 +20,110 @@ expand_var_still_repeating = variable '{$ident}' is still repeating at this depth expand_meta_var_dif_seq_matchers = {$msg} + +expand_macro_const_stability = + macros cannot have const stability attributes + .label = invalid const stability attribute + .label2 = const stability attribute affects this macro + +expand_macro_body_stability = + macros cannot have body stability attributes + .label = invalid body stability attribute + .label2 = body stability attribute affects this macro + +expand_resolve_relative_path = + cannot resolve relative path in non-file source `{$path}` + +expand_attr_no_arguments = + attribute must have either one or two arguments + +expand_not_a_meta_item = + not a meta item + +expand_only_one_word = + must only be one word + +expand_cannot_be_name_of_macro = + `{$trait_ident}` cannot be a name of {$macro_type} macro + +expand_arg_not_attributes = + second argument must be `attributes` + +expand_attributes_wrong_form = + attribute must be of form: `attributes(foo, bar)` + +expand_attribute_meta_item = + attribute must be a meta item, not a literal + +expand_attribute_single_word = + attribute must only be a single word + +expand_helper_attribute_name_invalid = + `{$name}` cannot be a name of derive helper attribute + +expand_expected_comma_in_list = + expected token: `,` + +expand_only_one_argument = + {$name} takes 1 argument + +expand_takes_no_arguments = + {$name} takes no arguments + +expand_feature_included_in_edition = + the feature `{$feature}` is included in the Rust {$edition} edition + +expand_feature_removed = + feature has been removed + .label = feature has been removed + .reason = {$reason} + +expand_feature_not_allowed = + the feature `{$name}` is not in the list of allowed features + +expand_recursion_limit_reached = + recursion limit reached while expanding `{$descr}` + .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) + +expand_malformed_feature_attribute = + malformed `feature` attribute input + .expected = expected just one word + +expand_remove_expr_not_supported = + removing an expression is not supported in this position + +expand_invalid_cfg_no_parens = `cfg` is not followed by parentheses +expand_invalid_cfg_no_predicate = `cfg` predicate is not specified +expand_invalid_cfg_multiple_predicates = multiple `cfg` predicates are specified +expand_invalid_cfg_predicate_literal = `cfg` predicate key cannot be a literal +expand_invalid_cfg_expected_syntax = expected syntax is + +expand_wrong_fragment_kind = + non-{$kind} macro in {$kind} position: {$name} + +expand_unsupported_key_value = + key-value macro attributes are not supported + +expand_incomplete_parse = + macro expansion ignores token `{$token}` and any following + .label = caused by the macro expansion here + .note = the usage of `{$macro_path}!` is likely invalid in {$kind_name} context + .suggestion_add_semi = you might be missing a semicolon here + +expand_remove_node_not_supported = + removing {$descr} is not supported in this position + +expand_module_circular = + circular modules: {$modules} + +expand_module_in_block = + cannot declare a non-inline module inside a block unless it has a path attribute + .note = maybe `use` the module `{$name}` instead of redeclaring it + +expand_module_file_not_found = + file not found for module `{$name}` + .help = to create the module `{$name}`, create file "{$default_path}" or "{$secondary_path}" + +expand_module_multiple_candidates = + file for module `{$name}` found at both "{$default_path}" and "{$secondary_path}" + .help = delete or rename one of them to remove the ambiguity diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 7155db32e53..cb39e997436 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -152,6 +152,12 @@ impl IntoDiagnosticArg for ast::Path { } } +impl IntoDiagnosticArg for &ast::Path { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(self))) + } +} + impl IntoDiagnosticArg for ast::token::Token { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(pprust::token_to_string(&self)) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index db595df8ec1..4df2198fb0e 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -24,7 +24,7 @@ use rustc_lint_defs::pluralize; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::sync::Lrc; -use rustc_error_messages::FluentArgs; +use rustc_error_messages::{FluentArgs, SpanLabel}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use std::borrow::Cow; use std::cmp::{max, min, Reverse}; @@ -773,6 +773,7 @@ impl EmitterWriter { draw_col_separator_no_space(buffer, line_offset, width_offset - 2); } + #[instrument(level = "trace", skip(self), ret)] fn render_source_line( &self, buffer: &mut StyledBuffer, @@ -804,6 +805,7 @@ impl EmitterWriter { Some(s) => normalize_whitespace(&s), None => return Vec::new(), }; + trace!(?source_string); let line_offset = buffer.num_lines(); @@ -1323,6 +1325,7 @@ impl EmitterWriter { } } + #[instrument(level = "trace", skip(self, args), ret)] fn emit_message_default( &mut self, msp: &MultiSpan, @@ -1384,22 +1387,15 @@ impl EmitterWriter { } } let mut annotated_files = FileWithAnnotatedLines::collect_annotations(self, args, msp); + trace!("{annotated_files:#?}"); // Make sure our primary file comes first - let (primary_lo, sm) = if let (Some(sm), Some(ref primary_span)) = - (self.sm.as_ref(), msp.primary_span().as_ref()) - { - if !primary_span.is_dummy() { - (sm.lookup_char_pos(primary_span.lo()), sm) - } else { - emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; - return Ok(()); - } - } else { + let primary_span = msp.primary_span().unwrap_or_default(); + let (Some(sm), false) = (self.sm.as_ref(), primary_span.is_dummy()) else { // If we don't have span information, emit and exit - emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; - return Ok(()); + return emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message); }; + let primary_lo = sm.lookup_char_pos(primary_span.lo()); if let Ok(pos) = annotated_files.binary_search_by(|x| x.file.name.cmp(&primary_lo.file.name)) { @@ -1410,6 +1406,54 @@ impl EmitterWriter { for annotated_file in annotated_files { // we can't annotate anything if the source is unavailable. if !sm.ensure_source_file_source_present(annotated_file.file.clone()) { + if !self.short_message { + // We'll just print an unannotated message. + for (annotation_id, line) in annotated_file.lines.into_iter().enumerate() { + let mut annotations = line.annotations.clone(); + annotations.sort_by_key(|a| Reverse(a.start_col)); + let mut line_idx = buffer.num_lines(); + buffer.append( + line_idx, + &format!( + "{}:{}:{}", + sm.filename_for_diagnostics(&annotated_file.file.name), + sm.doctest_offset_line(&annotated_file.file.name, line.line_index), + annotations[0].start_col + 1, + ), + Style::LineAndColumn, + ); + if annotation_id == 0 { + buffer.prepend(line_idx, "--> ", Style::LineNumber); + for _ in 0..max_line_num_len { + buffer.prepend(line_idx, " ", Style::NoStyle); + } + line_idx += 1; + }; + for (i, annotation) in annotations.into_iter().enumerate() { + if let Some(label) = &annotation.label { + let style = if annotation.is_primary { + Style::LabelPrimary + } else { + Style::LabelSecondary + }; + if annotation_id == 0 { + buffer.prepend(line_idx, " |", Style::LineNumber); + for _ in 0..max_line_num_len { + buffer.prepend(line_idx, " ", Style::NoStyle); + } + line_idx += 1; + buffer.append(line_idx + i, " = note: ", style); + for _ in 0..max_line_num_len { + buffer.prepend(line_idx, " ", Style::NoStyle); + } + } else { + buffer.append(line_idx + i, ": ", style); + } + buffer.append(line_idx + i, label, style); + } + } + } + } continue; } @@ -1656,6 +1700,7 @@ impl EmitterWriter { multilines.extend(&to_add); } } + trace!("buffer: {:#?}", buffer.render()); } if let Some(tracked) = emitted_at { @@ -1979,6 +2024,7 @@ impl EmitterWriter { Ok(()) } + #[instrument(level = "trace", skip(self, args, code, children, suggestions))] fn emit_messages_default( &mut self, level: &Level, @@ -2209,46 +2255,28 @@ impl FileWithAnnotatedLines { let mut multiline_annotations = vec![]; if let Some(ref sm) = emitter.source_map() { - for span_label in msp.span_labels() { - let fixup_lo_hi = |span: Span| { - let lo = sm.lookup_char_pos(span.lo()); - let mut hi = sm.lookup_char_pos(span.hi()); - - // Watch out for "empty spans". If we get a span like 6..6, we - // want to just display a `^` at 6, so convert that to - // 6..7. This is degenerate input, but it's best to degrade - // gracefully -- and the parser likes to supply a span like - // that for EOF, in particular. - - if lo.col_display == hi.col_display && lo.line == hi.line { - hi.col_display += 1; - } - (lo, hi) + for SpanLabel { span, is_primary, label } in msp.span_labels() { + // If we don't have a useful span, pick the primary span if that exists. + // Worst case we'll just print an error at the top of the main file. + let span = match (span.is_dummy(), msp.primary_span()) { + (_, None) | (false, _) => span, + (true, Some(span)) => span, }; - if span_label.span.is_dummy() { - if let Some(span) = msp.primary_span() { - // if we don't know where to render the annotation, emit it as a note - // on the primary span. - - let (lo, hi) = fixup_lo_hi(span); - - let ann = Annotation { - start_col: lo.col_display, - end_col: hi.col_display, - is_primary: span_label.is_primary, - label: span_label - .label - .as_ref() - .map(|m| emitter.translate_message(m, args).to_string()), - annotation_type: AnnotationType::Singleline, - }; - add_annotation_to_file(&mut output, lo.file, lo.line, ann); - } - continue; + let lo = sm.lookup_char_pos(span.lo()); + let mut hi = sm.lookup_char_pos(span.hi()); + + // Watch out for "empty spans". If we get a span like 6..6, we + // want to just display a `^` at 6, so convert that to + // 6..7. This is degenerate input, but it's best to degrade + // gracefully -- and the parser likes to supply a span like + // that for EOF, in particular. + + if lo.col_display == hi.col_display && lo.line == hi.line { + hi.col_display += 1; } - let (lo, hi) = fixup_lo_hi(span_label.span); + let label = label.as_ref().map(|m| emitter.translate_message(m, args).to_string()); if lo.line != hi.line { let ml = MultilineAnnotation { @@ -2257,11 +2285,8 @@ impl FileWithAnnotatedLines { line_end: hi.line, start_col: lo.col_display, end_col: hi.col_display, - is_primary: span_label.is_primary, - label: span_label - .label - .as_ref() - .map(|m| emitter.translate_message(m, args).to_string()), + is_primary, + label, overlaps_exactly: false, }; multiline_annotations.push((lo.file, ml)); @@ -2269,11 +2294,8 @@ impl FileWithAnnotatedLines { let ann = Annotation { start_col: lo.col_display, end_col: hi.col_display, - is_primary: span_label.is_primary, - label: span_label - .label - .as_ref() - .map(|m| emitter.translate_message(m, args).to_string()), + is_primary, + label, annotation_type: AnnotationType::Singleline, }; add_annotation_to_file(&mut output, lo.file, lo.line, ann); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 13e2d1ebbe7..6f159663e80 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1,3 +1,11 @@ +#![deny(rustc::untranslatable_diagnostic)] + +use crate::errors::{ + ArgumentNotAttributes, AttrNoArguments, AttributeMetaItem, AttributeSingleWord, + AttributesWrongForm, CannotBeNameOfMacro, ExpectedCommaInList, HelperAttributeNameInvalid, + MacroBodyStability, MacroConstStability, NotAMetaItem, OnlyOneArgument, OnlyOneWord, + ResolveRelativePath, TakesNoArguments, +}; use crate::expand::{self, AstFragment, Invocation}; use crate::module::DirOwnership; @@ -789,26 +797,16 @@ impl SyntaxExtension { .unwrap_or_else(|| (None, helper_attrs)); let (stability, const_stability, body_stability) = attr::find_stability(&sess, attrs, span); if let Some((_, sp)) = const_stability { - sess.parse_sess - .span_diagnostic - .struct_span_err(sp, "macros cannot have const stability attributes") - .span_label(sp, "invalid const stability attribute") - .span_label( - sess.source_map().guess_head_span(span), - "const stability attribute affects this macro", - ) - .emit(); + sess.emit_err(MacroConstStability { + span: sp, + head_span: sess.source_map().guess_head_span(span), + }); } if let Some((_, sp)) = body_stability { - sess.parse_sess - .span_diagnostic - .struct_span_err(sp, "macros cannot have body stability attributes") - .span_label(sp, "invalid body stability attribute") - .span_label( - sess.source_map().guess_head_span(span), - "body stability attribute affects this macro", - ) - .emit(); + sess.emit_err(MacroBodyStability { + span: sp, + head_span: sess.source_map().guess_head_span(span), + }); } SyntaxExtension { @@ -960,7 +958,7 @@ pub trait LintStoreExpand { node_id: NodeId, attrs: &[Attribute], items: &[P<Item>], - name: &str, + name: Symbol, ); } @@ -1200,13 +1198,11 @@ pub fn resolve_path( .expect("attempting to resolve a file path in an external file"), FileName::DocTest(path, _) => path, other => { - return Err(parse_sess.span_diagnostic.struct_span_err( + return Err(ResolveRelativePath { span, - &format!( - "cannot resolve relative path in non-file source `{}`", - parse_sess.source_map().filename_for_diagnostics(&other) - ), - )); + path: parse_sess.source_map().filename_for_diagnostics(&other).to_string(), + } + .into_diagnostic(&parse_sess.span_diagnostic)); } }; result.pop(); @@ -1222,6 +1218,8 @@ pub fn resolve_path( /// The returned bool indicates whether an applicable suggestion has already been /// added to the diagnostic to avoid emitting multiple suggestions. `Err(None)` /// indicates that an ast error was encountered. +// FIXME(Nilstrieb) Make this function setup translatable +#[allow(rustc::untranslatable_diagnostic)] pub fn expr_to_spanned_string<'a>( cx: &'a mut ExtCtxt<'_>, expr: P<ast::Expr>, @@ -1280,9 +1278,9 @@ pub fn expr_to_string( /// compilation should call /// `cx.parse_sess.span_diagnostic.abort_if_errors()` (this should be /// done as rarely as possible). -pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str) { +pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) { if !tts.is_empty() { - cx.span_err(sp, &format!("{} takes no arguments", name)); + cx.emit_err(TakesNoArguments { span, name }); } } @@ -1304,31 +1302,27 @@ pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option<P<ast::Expr>> { /// expect exactly one string literal, or emit an error and return `None`. pub fn get_single_str_from_tts( cx: &mut ExtCtxt<'_>, - sp: Span, + span: Span, tts: TokenStream, name: &str, ) -> Option<Symbol> { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { - cx.span_err(sp, &format!("{} takes 1 argument", name)); + cx.emit_err(OnlyOneArgument { span, name }); return None; } let ret = parse_expr(&mut p)?; let _ = p.eat(&token::Comma); if p.token != token::Eof { - cx.span_err(sp, &format!("{} takes 1 argument", name)); + cx.emit_err(OnlyOneArgument { span, name }); } expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s) } /// Extracts comma-separated expressions from `tts`. /// On error, emit it, and return `None`. -pub fn get_exprs_from_tts( - cx: &mut ExtCtxt<'_>, - sp: Span, - tts: TokenStream, -) -> Option<Vec<P<ast::Expr>>> { +pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>, tts: TokenStream) -> Option<Vec<P<ast::Expr>>> { let mut p = cx.new_parser_from_tts(tts); let mut es = Vec::new(); while p.token != token::Eof { @@ -1343,7 +1337,7 @@ pub fn get_exprs_from_tts( continue; } if p.token != token::Eof { - cx.span_err(sp, "expected token: `,`"); + cx.emit_err(ExpectedCommaInList { span: p.token.span }); return None; } } @@ -1353,64 +1347,58 @@ pub fn get_exprs_from_tts( pub fn parse_macro_name_and_helper_attrs( diag: &rustc_errors::Handler, attr: &Attribute, - descr: &str, + macro_type: &str, ) -> Option<(Symbol, Vec<Symbol>)> { // Once we've located the `#[proc_macro_derive]` attribute, verify // that it's of the form `#[proc_macro_derive(Foo)]` or // `#[proc_macro_derive(Foo, attributes(A, ..))]` let list = attr.meta_item_list()?; if list.len() != 1 && list.len() != 2 { - diag.span_err(attr.span, "attribute must have either one or two arguments"); + diag.emit_err(AttrNoArguments { span: attr.span }); return None; } let Some(trait_attr) = list[0].meta_item() else { - diag.span_err(list[0].span(), "not a meta item"); + diag.emit_err(NotAMetaItem {span: list[0].span()}); return None; }; let trait_ident = match trait_attr.ident() { Some(trait_ident) if trait_attr.is_word() => trait_ident, _ => { - diag.span_err(trait_attr.span, "must only be one word"); + diag.emit_err(OnlyOneWord { span: trait_attr.span }); return None; } }; if !trait_ident.name.can_be_raw() { - diag.span_err( - trait_attr.span, - &format!("`{}` cannot be a name of {} macro", trait_ident, descr), - ); + diag.emit_err(CannotBeNameOfMacro { span: trait_attr.span, trait_ident, macro_type }); } let attributes_attr = list.get(1); let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { if !attr.has_name(sym::attributes) { - diag.span_err(attr.span(), "second argument must be `attributes`"); + diag.emit_err(ArgumentNotAttributes { span: attr.span() }); } attr.meta_item_list() .unwrap_or_else(|| { - diag.span_err(attr.span(), "attribute must be of form: `attributes(foo, bar)`"); + diag.emit_err(AttributesWrongForm { span: attr.span() }); &[] }) .iter() .filter_map(|attr| { let Some(attr) = attr.meta_item() else { - diag.span_err(attr.span(), "not a meta item"); + diag.emit_err(AttributeMetaItem { span: attr.span() }); return None; }; let ident = match attr.ident() { Some(ident) if attr.is_word() => ident, _ => { - diag.span_err(attr.span, "must only be one word"); + diag.emit_err(AttributeSingleWord { span: attr.span }); return None; } }; if !ident.name.can_be_raw() { - diag.span_err( - attr.span, - &format!("`{}` cannot be a name of derive helper attribute", ident), - ); + diag.emit_err(HelperAttributeNameInvalid { span: attr.span, name: ident }); } Some(ident.name) diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 2510795c2e3..f4c6f3386ad 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -1,5 +1,9 @@ //! Conditional compilation stripping. +use crate::errors::{ + FeatureIncludedInEdition, FeatureNotAllowed, FeatureRemoved, FeatureRemovedReason, InvalidCfg, + MalformedFeatureAttribute, MalformedFeatureAttributeHelp, RemoveExprNotSupported, +}; use rustc_ast::ptr::P; use rustc_ast::token::{Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree}; @@ -10,7 +14,6 @@ use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::map_in_place::MapInPlace; -use rustc_errors::{error_code, struct_span_err, Applicability, Handler}; use rustc_feature::{Feature, Features, State as FeatureState}; use rustc_feature::{ ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES, @@ -33,18 +36,12 @@ pub struct StripUnconfigured<'a> { pub lint_node_id: NodeId, } -fn get_features( - sess: &Session, - span_handler: &Handler, - krate_attrs: &[ast::Attribute], -) -> Features { - fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { - let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); - err.span_label(span, "feature has been removed"); - if let Some(reason) = reason { - err.note(reason); - } - err.emit(); +fn get_features(sess: &Session, krate_attrs: &[ast::Attribute]) -> Features { + fn feature_removed(sess: &Session, span: Span, reason: Option<&str>) { + sess.emit_err(FeatureRemoved { + span, + reason: reason.map(|reason| FeatureRemovedReason { reason }), + }); } fn active_features_up_to(edition: Edition) -> impl Iterator<Item = &'static Feature> { @@ -117,34 +114,34 @@ fn get_features( continue; }; - let bad_input = |span| { - struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input") - }; - for mi in list { let name = match mi.ident() { Some(ident) if mi.is_word() => ident.name, Some(ident) => { - bad_input(mi.span()) - .span_suggestion( - mi.span(), - "expected just one word", - ident.name, - Applicability::MaybeIncorrect, - ) - .emit(); + sess.emit_err(MalformedFeatureAttribute { + span: mi.span(), + help: MalformedFeatureAttributeHelp::Suggestion { + span: mi.span(), + suggestion: ident.name, + }, + }); continue; } None => { - bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit(); + sess.emit_err(MalformedFeatureAttribute { + span: mi.span(), + help: MalformedFeatureAttributeHelp::Label { span: mi.span() }, + }); continue; } }; - if let Some(edition) = edition_enabled_features.get(&name) { - let msg = - &format!("the feature `{}` is included in the Rust {} edition", name, edition); - span_handler.struct_span_warn_with_code(mi.span(), msg, error_code!(E0705)).emit(); + if let Some(&edition) = edition_enabled_features.get(&name) { + sess.emit_warning(FeatureIncludedInEdition { + span: mi.span(), + feature: name, + edition, + }); continue; } @@ -159,7 +156,7 @@ fn get_features( if let FeatureState::Removed { reason } | FeatureState::Stabilized { reason } = state { - feature_removed(span_handler, mi.span(), *reason); + feature_removed(sess, mi.span(), *reason); continue; } } @@ -173,14 +170,7 @@ fn get_features( if let Some(allowed) = sess.opts.unstable_opts.allow_features.as_ref() { if allowed.iter().all(|f| name.as_str() != f) { - struct_span_err!( - span_handler, - mi.span(), - E0725, - "the feature `{}` is not in the list of allowed features", - name - ) - .emit(); + sess.emit_err(FeatureNotAllowed { span: mi.span(), name }); continue; } } @@ -221,7 +211,7 @@ pub fn features( } Some(attrs) => { krate.attrs = attrs; - let features = get_features(sess, diag, &krate.attrs); + let features = get_features(sess, &krate.attrs); if err_count == diag.err_count() { // Avoid reconfiguring malformed `cfg_attr`s. strip_unconfigured.features = Some(&features); @@ -503,8 +493,7 @@ impl<'a> StripUnconfigured<'a> { // N.B., this is intentionally not part of the visit_expr() function // in order for filter_map_expr() to be able to avoid this check if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(*a)) { - let msg = "removing an expression is not supported in this position"; - self.sess.parse_sess.span_diagnostic.span_err(attr.span, msg); + self.sess.emit_err(RemoveExprNotSupported { span: attr.span }); } self.process_cfg_attrs(expr); @@ -513,27 +502,26 @@ impl<'a> StripUnconfigured<'a> { } pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a MetaItem> { - let error = |span, msg, suggestion: &str| { - let mut err = sess.parse_sess.span_diagnostic.struct_span_err(span, msg); - if !suggestion.is_empty() { - err.span_suggestion( - span, - "expected syntax is", - suggestion, - Applicability::HasPlaceholders, - ); - } - err.emit(); - None - }; let span = meta_item.span; match meta_item.meta_item_list() { - None => error(span, "`cfg` is not followed by parentheses", "cfg(/* predicate */)"), - Some([]) => error(span, "`cfg` predicate is not specified", ""), - Some([_, .., l]) => error(l.span(), "multiple `cfg` predicates are specified", ""), + None => { + sess.emit_err(InvalidCfg::NotFollowedByParens { span }); + None + } + Some([]) => { + sess.emit_err(InvalidCfg::NoPredicate { span }); + None + } + Some([_, .., l]) => { + sess.emit_err(InvalidCfg::MultiplePredicates { span: l.span() }); + None + } Some([single]) => match single.meta_item() { Some(meta_item) => Some(meta_item), - None => error(single.span(), "`cfg` predicate key cannot be a literal", ""), + None => { + sess.emit_err(InvalidCfg::PredicateLiteral { span: single.span() }); + None + } }, } } diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index d383f4832f6..afe5169d3f5 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -1,6 +1,10 @@ +use rustc_ast::ast; use rustc_macros::Diagnostic; -use rustc_span::symbol::MacroRulesNormalizedIdent; -use rustc_span::Span; +use rustc_session::Limit; +use rustc_span::edition::Edition; +use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent}; +use rustc_span::{Span, Symbol}; +use std::borrow::Cow; #[derive(Diagnostic)] #[diag(expand_expr_repeat_no_syntax_vars)] @@ -46,3 +50,321 @@ pub(crate) struct MetaVarsDifSeqMatchers { pub span: Span, pub msg: String, } + +#[derive(Diagnostic)] +#[diag(expand_resolve_relative_path)] +pub(crate) struct ResolveRelativePath { + #[primary_span] + pub span: Span, + pub path: String, +} + +#[derive(Diagnostic)] +#[diag(expand_macro_const_stability)] +pub(crate) struct MacroConstStability { + #[primary_span] + #[label] + pub span: Span, + #[label(label2)] + pub head_span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_macro_body_stability)] +pub(crate) struct MacroBodyStability { + #[primary_span] + #[label] + pub span: Span, + #[label(label2)] + pub head_span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_attr_no_arguments)] +pub(crate) struct AttrNoArguments { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_not_a_meta_item)] +pub(crate) struct NotAMetaItem { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_only_one_word)] +pub(crate) struct OnlyOneWord { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_cannot_be_name_of_macro)] +pub(crate) struct CannotBeNameOfMacro<'a> { + #[primary_span] + pub span: Span, + pub trait_ident: Ident, + pub macro_type: &'a str, +} + +#[derive(Diagnostic)] +#[diag(expand_arg_not_attributes)] +pub(crate) struct ArgumentNotAttributes { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_attributes_wrong_form)] +pub(crate) struct AttributesWrongForm { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_attribute_meta_item)] +pub(crate) struct AttributeMetaItem { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_attribute_single_word)] +pub(crate) struct AttributeSingleWord { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_helper_attribute_name_invalid)] +pub(crate) struct HelperAttributeNameInvalid { + #[primary_span] + pub span: Span, + pub name: Ident, +} + +#[derive(Diagnostic)] +#[diag(expand_expected_comma_in_list)] +pub(crate) struct ExpectedCommaInList { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_only_one_argument)] +pub(crate) struct OnlyOneArgument<'a> { + #[primary_span] + pub span: Span, + pub name: &'a str, +} + +#[derive(Diagnostic)] +#[diag(expand_takes_no_arguments)] +pub(crate) struct TakesNoArguments<'a> { + #[primary_span] + pub span: Span, + pub name: &'a str, +} + +#[derive(Diagnostic)] +#[diag(expand_feature_included_in_edition, code = "E0705")] +pub(crate) struct FeatureIncludedInEdition { + #[primary_span] + pub span: Span, + pub feature: Symbol, + pub edition: Edition, +} + +#[derive(Diagnostic)] +#[diag(expand_feature_removed, code = "E0557")] +pub(crate) struct FeatureRemoved<'a> { + #[primary_span] + #[label] + pub span: Span, + #[subdiagnostic] + pub reason: Option<FeatureRemovedReason<'a>>, +} + +#[derive(Subdiagnostic)] +#[note(reason)] +pub(crate) struct FeatureRemovedReason<'a> { + pub reason: &'a str, +} + +#[derive(Diagnostic)] +#[diag(expand_feature_not_allowed, code = "E0725")] +pub(crate) struct FeatureNotAllowed { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(expand_recursion_limit_reached)] +#[help] +pub(crate) struct RecursionLimitReached<'a> { + #[primary_span] + pub span: Span, + pub descr: String, + pub suggested_limit: Limit, + pub crate_name: &'a str, +} + +#[derive(Diagnostic)] +#[diag(expand_malformed_feature_attribute, code = "E0556")] +pub(crate) struct MalformedFeatureAttribute { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub help: MalformedFeatureAttributeHelp, +} + +#[derive(Subdiagnostic)] +pub(crate) enum MalformedFeatureAttributeHelp { + #[label(expected)] + Label { + #[primary_span] + span: Span, + }, + #[suggestion(expected, code = "{suggestion}", applicability = "maybe-incorrect")] + Suggestion { + #[primary_span] + span: Span, + suggestion: Symbol, + }, +} + +#[derive(Diagnostic)] +#[diag(expand_remove_expr_not_supported)] +pub(crate) struct RemoveExprNotSupported { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +pub(crate) enum InvalidCfg { + #[diag(expand_invalid_cfg_no_parens)] + NotFollowedByParens { + #[primary_span] + #[suggestion( + expand_invalid_cfg_expected_syntax, + code = "cfg(/* predicate */)", + applicability = "has-placeholders" + )] + span: Span, + }, + #[diag(expand_invalid_cfg_no_predicate)] + NoPredicate { + #[primary_span] + #[suggestion( + expand_invalid_cfg_expected_syntax, + code = "cfg(/* predicate */)", + applicability = "has-placeholders" + )] + span: Span, + }, + #[diag(expand_invalid_cfg_multiple_predicates)] + MultiplePredicates { + #[primary_span] + span: Span, + }, + #[diag(expand_invalid_cfg_predicate_literal)] + PredicateLiteral { + #[primary_span] + span: Span, + }, +} + +#[derive(Diagnostic)] +#[diag(expand_wrong_fragment_kind)] +pub(crate) struct WrongFragmentKind<'a> { + #[primary_span] + pub span: Span, + pub kind: &'a str, + pub name: &'a ast::Path, +} + +#[derive(Diagnostic)] +#[diag(expand_unsupported_key_value)] +pub(crate) struct UnsupportedKeyValue { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_incomplete_parse)] +#[note] +pub(crate) struct IncompleteParse<'a> { + #[primary_span] + pub span: Span, + pub token: Cow<'a, str>, + #[label] + pub label_span: Span, + pub macro_path: &'a ast::Path, + pub kind_name: &'a str, + + #[suggestion( + suggestion_add_semi, + style = "verbose", + code = ";", + applicability = "maybe-incorrect" + )] + pub add_semicolon: Option<Span>, +} + +#[derive(Diagnostic)] +#[diag(expand_remove_node_not_supported)] +pub(crate) struct RemoveNodeNotSupported { + #[primary_span] + pub span: Span, + pub descr: &'static str, +} + +#[derive(Diagnostic)] +#[diag(expand_module_circular)] +pub(crate) struct ModuleCircular { + #[primary_span] + pub span: Span, + pub modules: String, +} + +#[derive(Diagnostic)] +#[diag(expand_module_in_block)] +pub(crate) struct ModuleInBlock { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub name: Option<ModuleInBlockName>, +} + +#[derive(Subdiagnostic)] +#[note(note)] +pub(crate) struct ModuleInBlockName { + #[primary_span] + pub span: Span, + pub name: Ident, +} + +#[derive(Diagnostic)] +#[diag(expand_module_file_not_found, code = "E0583")] +#[help] +pub(crate) struct ModuleFileNotFound { + #[primary_span] + pub span: Span, + pub name: Ident, + pub default_path: String, + pub secondary_path: String, +} + +#[derive(Diagnostic)] +#[diag(expand_module_multiple_candidates, code = "E0761")] +#[help] +pub(crate) struct ModuleMultipleCandidates { + #[primary_span] + pub span: Span, + pub name: Ident, + pub default_path: String, + pub secondary_path: String, +} diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index e799fa404f6..e26c16dcd7e 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1,5 +1,9 @@ use crate::base::*; use crate::config::StripUnconfigured; +use crate::errors::{ + IncompleteParse, RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, + UnsupportedKeyValue, WrongFragmentKind, +}; use crate::hygiene::SyntaxContext; use crate::mbe::diagnostics::annotate_err_with_kind; use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod}; @@ -18,7 +22,7 @@ use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind}; use rustc_ast_pretty::pprust; use rustc_data_structures::map_in_place::MapInPlace; use rustc_data_structures::sync::Lrc; -use rustc_errors::{Applicability, PResult}; +use rustc_errors::PResult; use rustc_feature::Features; use rustc_parse::parser::{ AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser, RecoverColon, RecoverComma, @@ -606,29 +610,22 @@ impl<'a, 'b> MacroExpander<'a, 'b> { Limit(0) => Limit(2), limit => limit * 2, }; - self.cx - .struct_span_err( - expn_data.call_site, - &format!("recursion limit reached while expanding `{}`", expn_data.kind.descr()), - ) - .help(&format!( - "consider increasing the recursion limit by adding a \ - `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)", - suggested_limit, self.cx.ecfg.crate_name, - )) - .emit(); + + self.cx.emit_err(RecursionLimitReached { + span: expn_data.call_site, + descr: expn_data.kind.descr(), + suggested_limit, + crate_name: &self.cx.ecfg.crate_name, + }); + self.cx.trace_macros_diag(); } /// A macro's expansion does not fit in this fragment kind. /// For example, a non-type macro in a type position. fn error_wrong_fragment_kind(&mut self, kind: AstFragmentKind, mac: &ast::MacCall, span: Span) { - let msg = format!( - "non-{kind} macro in {kind} position: {path}", - kind = kind.name(), - path = pprust::path_to_string(&mac.path), - ); - self.cx.span_err(span, &msg); + self.cx.emit_err(WrongFragmentKind { span, kind: kind.name(), name: &mac.path }); + self.cx.trace_macros_diag(); } @@ -707,7 +704,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let attr_item = attr.unwrap_normal_item(); if let AttrArgs::Eq(..) = attr_item.args { - self.cx.span_err(span, "key-value macro attributes are not supported"); + self.cx.emit_err(UnsupportedKeyValue { span }); } let inner_tokens = attr_item.args.inner_tokens(); let Ok(tok_result) = expander.expand(self.cx, span, inner_tokens, tokens) else { @@ -729,9 +726,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } }; if fragment_kind == AstFragmentKind::Expr && items.is_empty() { - let msg = - "removing an expression is not supported in this position"; - self.cx.span_err(span, msg); + self.cx.emit_err(RemoveExprNotSupported { span }); fragment_kind.dummy(span) } else { fragment_kind.expect_from_annotatables(items) @@ -939,38 +934,32 @@ pub fn parse_ast_fragment<'a>( } pub fn ensure_complete_parse<'a>( - this: &mut Parser<'a>, + parser: &mut Parser<'a>, macro_path: &ast::Path, kind_name: &str, span: Span, ) { - if this.token != token::Eof { - let token = pprust::token_to_string(&this.token); - let msg = format!("macro expansion ignores token `{}` and any following", token); + if parser.token != token::Eof { + let token = pprust::token_to_string(&parser.token); // Avoid emitting backtrace info twice. - let def_site_span = this.token.span.with_ctxt(SyntaxContext::root()); - let mut err = this.struct_span_err(def_site_span, &msg); - err.span_label(span, "caused by the macro expansion here"); - let msg = format!( - "the usage of `{}!` is likely invalid in {} context", - pprust::path_to_string(macro_path), - kind_name, - ); - err.note(&msg); + let def_site_span = parser.token.span.with_ctxt(SyntaxContext::root()); - let semi_span = this.sess.source_map().next_point(span); - match this.sess.source_map().span_to_snippet(semi_span) { + let semi_span = parser.sess.source_map().next_point(span); + let add_semicolon = match parser.sess.source_map().span_to_snippet(semi_span) { Ok(ref snippet) if &snippet[..] != ";" && kind_name == "expression" => { - err.span_suggestion( - span.shrink_to_hi(), - "you might be missing a semicolon here", - ";", - Applicability::MaybeIncorrect, - ); + Some(span.shrink_to_hi()) } - _ => {} - } - err.emit(); + _ => None, + }; + + parser.sess.emit_err(IncompleteParse { + span: def_site_span, + token, + label_span: span, + macro_path, + kind_name, + add_semicolon, + }); } } @@ -1122,7 +1111,7 @@ impl InvocationCollectorNode for P<ast::Item> { ecx.current_expansion.lint_node_id, &attrs, &items, - ident.name.as_str(), + ident.name, ); } @@ -1766,9 +1755,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { if self.expand_cfg_true(node, attr, pos) { continue; } - let msg = - format!("removing {} is not supported in this position", Node::descr()); - self.cx.span_err(span, &msg); + + self.cx.emit_err(RemoveNodeNotSupported { span, descr: Node::descr() }); continue; } sym::cfg_attr => { diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index b34de94fb7d..89726856635 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -10,6 +10,7 @@ #![feature(rustc_attrs)] #![feature(try_blocks)] #![recursion_limit = "256"] +#![deny(rustc::untranslatable_diagnostic)] #[macro_use] extern crate rustc_macros; @@ -31,8 +32,13 @@ pub mod config; pub mod errors; pub mod expand; pub mod module; + +// FIXME(Nilstrieb) Translate proc_macro diagnostics +#[allow(rustc::untranslatable_diagnostic)] pub mod proc_macro; +// FIXME(Nilstrieb) Translate macro_rules diagnostics +#[allow(rustc::untranslatable_diagnostic)] pub(crate) mod mbe; // HACK(Centril, #64197): These shouldn't really be here. diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 9002a24e42f..07f47a9c3a4 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -1,13 +1,17 @@ use crate::base::ModuleData; +use crate::errors::{ + ModuleCircular, ModuleFileNotFound, ModuleInBlock, ModuleInBlockName, ModuleMultipleCandidates, +}; use rustc_ast::ptr::P; use rustc_ast::{token, AttrVec, Attribute, Inline, Item, ModSpans}; -use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_parse::new_parser_from_file; use rustc_parse::validate_attr; use rustc_session::parse::ParseSess; use rustc_session::Session; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; +use std::iter::once; use std::path::{self, Path, PathBuf}; @@ -242,57 +246,41 @@ pub fn default_submod_path<'a>( impl ModError<'_> { fn report(self, sess: &Session, span: Span) -> ErrorGuaranteed { - let diag = &sess.parse_sess.span_diagnostic; match self { ModError::CircularInclusion(file_paths) => { - let mut msg = String::from("circular modules: "); - for file_path in &file_paths { - msg.push_str(&file_path.display().to_string()); - msg.push_str(" -> "); - } - msg.push_str(&file_paths[0].display().to_string()); - diag.struct_span_err(span, &msg) - } - ModError::ModInBlock(ident) => { - let msg = "cannot declare a non-inline module inside a block unless it has a path attribute"; - let mut err = diag.struct_span_err(span, msg); - if let Some(ident) = ident { - let note = - format!("maybe `use` the module `{}` instead of redeclaring it", ident); - err.span_note(span, ¬e); - } - err + let path_to_string = |path: &PathBuf| path.display().to_string(); + + let paths = file_paths + .iter() + .map(path_to_string) + .chain(once(path_to_string(&file_paths[0]))) + .collect::<Vec<_>>(); + + let modules = paths.join(" -> "); + + sess.emit_err(ModuleCircular { span, modules }) } - ModError::FileNotFound(ident, default_path, secondary_path) => { - let mut err = struct_span_err!( - diag, + ModError::ModInBlock(ident) => sess.emit_err(ModuleInBlock { + span, + name: ident.map(|name| ModuleInBlockName { span, name }), + }), + ModError::FileNotFound(name, default_path, secondary_path) => { + sess.emit_err(ModuleFileNotFound { span, - E0583, - "file not found for module `{}`", - ident, - ); - err.help(&format!( - "to create the module `{}`, create file \"{}\" or \"{}\"", - ident, - default_path.display(), - secondary_path.display(), - )); - err + name, + default_path: default_path.display().to_string(), + secondary_path: secondary_path.display().to_string(), + }) } - ModError::MultipleCandidates(ident, default_path, secondary_path) => { - let mut err = struct_span_err!( - diag, + ModError::MultipleCandidates(name, default_path, secondary_path) => { + sess.emit_err(ModuleMultipleCandidates { span, - E0761, - "file for module `{}` found at both \"{}\" and \"{}\"", - ident, - default_path.display(), - secondary_path.display(), - ); - err.help("delete or rename one of them to remove the ambiguity"); - err + name, + default_path: default_path.display().to_string(), + secondary_path: secondary_path.display().to_string(), + }) } - ModError::ParserError(err) => err, - }.emit() + ModError::ParserError(mut err) => err.emit(), + } } } diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 539b04535a0..8f3bea29ffd 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -154,6 +154,7 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: & false, ); let handler = Handler::with_emitter(true, None, Box::new(emitter)); + #[allow(rustc::untranslatable_diagnostic)] handler.span_err(msp, "foo"); assert!( diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 4b6e068db43..6d8e78a0f18 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -394,7 +394,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ungated!(instruction_set, Normal, template!(List: "set"), ErrorPreceding), gated!( no_sanitize, Normal, - template!(List: "address, memory, thread"), DuplicatesOk, + template!(List: "address, kcfi, memory, thread"), DuplicatesOk, experimental!(no_sanitize) ), gated!(no_coverage, Normal, template!(Word), WarnFollowing, experimental!(no_coverage)), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 636e6e1b48d..8bc022e1e17 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -827,7 +827,7 @@ impl<'tcx> AttributeMap<'tcx> { pub struct OwnerNodes<'tcx> { /// Pre-computed hash of the full HIR. pub hash_including_bodies: Fingerprint, - /// Pre-computed hash of the item signature, sithout recursing into the body. + /// Pre-computed hash of the item signature, without recursing into the body. pub hash_without_bodies: Fingerprint, /// Full HIR for the current owner. // The zeroth node's parent should never be accessed: the owner's parent is computed by the diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs index 4636d515249..d4791150947 100644 --- a/compiler/rustc_hir/src/tests.rs +++ b/compiler/rustc_hir/src/tests.rs @@ -1,5 +1,7 @@ use crate::definitions::{DefKey, DefPathData, DisambiguatedDefPathData}; use rustc_span::def_id::{DefPathHash, StableCrateId}; +use rustc_span::edition::Edition; +use rustc_span::{create_session_if_not_set_then, Symbol}; #[test] fn def_path_hash_depends_on_crate_id() { @@ -11,26 +13,28 @@ fn def_path_hash_depends_on_crate_id() { // the crate by changing the crate disambiguator (e.g. via bumping the // crate's version number). - let id0 = StableCrateId::new("foo", false, vec!["1".to_string()]); - let id1 = StableCrateId::new("foo", false, vec!["2".to_string()]); + create_session_if_not_set_then(Edition::Edition2024, |_| { + let id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()]); + let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()]); - let h0 = mk_test_hash(id0); - let h1 = mk_test_hash(id1); + let h0 = mk_test_hash(id0); + let h1 = mk_test_hash(id1); - assert_ne!(h0.stable_crate_id(), h1.stable_crate_id()); - assert_ne!(h0.local_hash(), h1.local_hash()); + assert_ne!(h0.stable_crate_id(), h1.stable_crate_id()); + assert_ne!(h0.local_hash(), h1.local_hash()); - fn mk_test_hash(stable_crate_id: StableCrateId) -> DefPathHash { - let parent_hash = DefPathHash::new(stable_crate_id, 0); + fn mk_test_hash(stable_crate_id: StableCrateId) -> DefPathHash { + let parent_hash = DefPathHash::new(stable_crate_id, 0); - let key = DefKey { - parent: None, - disambiguated_data: DisambiguatedDefPathData { - data: DefPathData::CrateRoot, - disambiguator: 0, - }, - }; + let key = DefKey { + parent: None, + disambiguated_data: DisambiguatedDefPathData { + data: DefPathData::CrateRoot, + disambiguator: 0, + }, + }; - key.compute_stable_hash(parent_hash) - } + key.compute_stable_hash(parent_hash) + } + }) } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 945361ef43a..72288e5bc76 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -955,7 +955,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { .struct_span_err( attr.span, "the `#[rustc_must_implement_one_of]` attribute must be \ - used with at least 2 args", + used with at least 2 args", ) .emit(); @@ -987,7 +987,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { tcx.sess .struct_span_err( item.span, - "This function doesn't have a default implementation", + "function doesn't have a default implementation", ) .span_note(attr_span, "required by this annotation") .emit(); @@ -999,17 +999,17 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { } Some(item) => { tcx.sess - .struct_span_err(item.span, "Not a function") + .struct_span_err(item.span, "not a function") .span_note(attr_span, "required by this annotation") .note( - "All `#[rustc_must_implement_one_of]` arguments \ - must be associated function names", + "all `#[rustc_must_implement_one_of]` arguments must be associated \ + function names", ) .emit(); } None => { tcx.sess - .struct_span_err(ident.span, "Function not found in this trait") + .struct_span_err(ident.span, "function not found in this trait") .emit(); } } @@ -1027,11 +1027,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { for ident in &*list { if let Some(dup) = set.insert(ident.name, ident.span) { tcx.sess - .struct_span_err(vec![dup, ident.span], "Functions names are duplicated") - .note( - "All `#[rustc_must_implement_one_of]` arguments \ - must be unique", - ) + .struct_span_err(vec![dup, ident.span], "functions names are duplicated") + .note("all `#[rustc_must_implement_one_of]` arguments must be unique") .emit(); no_dups = false; @@ -1849,6 +1846,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { codegen_fn_attrs.no_sanitize |= SanitizerSet::ADDRESS; } else if item.has_name(sym::cfi) { codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI; + } else if item.has_name(sym::kcfi) { + codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI; } else if item.has_name(sym::memory) { codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY; } else if item.has_name(sym::memtag) { @@ -1862,7 +1861,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { } else { tcx.sess .struct_span_err(item.span(), "invalid argument for `no_sanitize`") - .note("expected one of: `address`, `cfi`, `hwaddress`, `memory`, `memtag`, `shadow-call-stack`, or `thread`") + .note("expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`") .emit(); } } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 639f81f20bf..cb4c35c0ce1 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -4,7 +4,6 @@ use hir::{ GenericParamKind, HirId, Node, }; use rustc_hir as hir; -use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint; @@ -79,7 +78,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { let generics = tcx.generics_of(parent_def_id.to_def_id()); let param_def_idx = generics.param_def_id_to_index[¶m_id.to_def_id()]; // In the above example this would be .params[..N#0] - let params = generics.params[..param_def_idx as usize].to_owned(); + let params = generics.params_to(param_def_idx as usize, tcx).to_owned(); let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect(); @@ -143,20 +142,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { Some(tcx.typeck_root_def_id(def_id)) } Node::Item(item) => match item.kind { - ItemKind::OpaqueTy(hir::OpaqueTy { - origin: - hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id), - in_trait, - .. - }) => { - if in_trait { - assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn)) - } else { - assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn)) - } - Some(fn_def_id.to_def_id()) - } - ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => { + ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => { let parent_id = tcx.hir().get_parent_item(hir_id); assert_ne!(parent_id, hir::CRATE_OWNER_ID); debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 0c9a350c295..32f86b8042c 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -1,7 +1,7 @@ use crate::coercion::CoerceMany; use crate::gather_locals::GatherLocalsVisitor; use crate::FnCtxt; -use crate::{GeneratorTypes, UnsafetyState}; +use crate::GeneratorTypes; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::intravisit::Visitor; @@ -30,7 +30,6 @@ pub(super) fn check_fn<'a, 'tcx>( can_be_generator: Option<hir::Movability>, ) -> Option<GeneratorTypes<'tcx>> { let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id); - fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id)); let tcx = fcx.tcx; let hir = tcx.hir(); diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 24184bdbf5c..6763e06c0cf 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -189,7 +189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, - error: Option<TypeError<'_>>, + error: Option<TypeError<'tcx>>, ) { let parent = self.tcx.hir().get_parent_node(expr.hir_id); match (self.tcx.hir().find(parent), error) { @@ -286,6 +286,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.downgrade_to_delayed_bug(); } } + ( + Some(hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Binary(_, lhs, rhs), .. + })), + Some(TypeError::Sorts(ExpectedFound { expected, .. })), + ) if rhs.hir_id == expr.hir_id + && self.typeck_results.borrow().expr_ty_adjusted_opt(lhs) == Some(expected) => + { + err.span_label(lhs.span, &format!("expected because this is `{expected}`")); + } _ => {} } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 8a875e05b19..60fec05d36d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1393,8 +1393,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { blk: &'tcx hir::Block<'tcx>, expected: Expectation<'tcx>, ) -> Ty<'tcx> { - let prev = self.ps.replace(self.ps.get().recurse(blk)); - // In some cases, blocks have just one exit, but other blocks // can be targeted by multiple breaks. This can happen both // with labeled blocks as well as when we desugar @@ -1558,7 +1556,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_ty(blk.hir_id, ty); - self.ps.set(prev); ty } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 1e9b5752130..30b59da7852 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -8,7 +8,7 @@ use rustc_errors::ErrorGuaranteed; pub use suggestions::*; use crate::coercion::DynamicCoerceMany; -use crate::{Diverges, EnclosingBreakables, Inherited, UnsafetyState}; +use crate::{Diverges, EnclosingBreakables, Inherited}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir_analysis::astconv::AstConv; @@ -74,8 +74,6 @@ pub struct FnCtxt<'a, 'tcx> { pub(super) resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>, - pub(super) ps: Cell<UnsafetyState>, - /// Whether the last checked node generates a divergence (e.g., /// `return` will set this to `Always`). In general, when entering /// an expression or other node in the tree, the initial value @@ -129,7 +127,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ret_coercion: None, ret_coercion_span: Cell::new(None), resume_yield_tys: None, - ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)), diverges: Cell::new(Diverges::Maybe), enclosing_breakables: RefCell::new(EnclosingBreakables { stack: Vec::new(), diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 09bd123350d..5b2352cda34 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -89,38 +89,6 @@ pub struct LocalTy<'tcx> { revealed_ty: Ty<'tcx>, } -#[derive(Copy, Clone)] -pub struct UnsafetyState { - pub def: hir::HirId, - pub unsafety: hir::Unsafety, - from_fn: bool, -} - -impl UnsafetyState { - pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState { - UnsafetyState { def, unsafety, from_fn: true } - } - - pub fn recurse(self, blk: &hir::Block<'_>) -> UnsafetyState { - use hir::BlockCheckMode; - match self.unsafety { - // If this unsafe, then if the outer function was already marked as - // unsafe we shouldn't attribute the unsafe'ness to the block. This - // way the block can be warned about instead of ignoring this - // extraneous block (functions are never warned about). - hir::Unsafety::Unsafe if self.from_fn => self, - - unsafety => { - let (unsafety, def) = match blk.rules { - BlockCheckMode::UnsafeBlock(..) => (hir::Unsafety::Unsafe, blk.hir_id), - BlockCheckMode::DefaultBlock => (unsafety, self.def), - }; - UnsafetyState { def, unsafety, from_fn: false } - } - } - } -} - /// If this `DefId` is a "primary tables entry", returns /// `Some((body_id, body_ty, fn_sig))`. Otherwise, returns `None`. /// diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 58d6e6d7efd..97ebed05855 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -109,6 +109,7 @@ use rustc_data_structures::{base_n, flock}; use rustc_errors::ErrorGuaranteed; use rustc_fs_util::{link_or_copy, LinkOrCopy}; use rustc_session::{Session, StableCrateId}; +use rustc_span::Symbol; use std::fs as std_fs; use std::io::{self, ErrorKind}; @@ -202,7 +203,7 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu /// [`rustc_interface::queries::dep_graph`]: ../../rustc_interface/struct.Queries.html#structfield.dep_graph pub fn prepare_session_directory( sess: &Session, - crate_name: &str, + crate_name: Symbol, stable_crate_id: StableCrateId, ) -> Result<(), ErrorGuaranteed> { if sess.opts.incremental.is_none() { @@ -657,7 +658,7 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> { Ok(UNIX_EPOCH + duration) } -fn crate_path(sess: &Session, crate_name: &str, stable_crate_id: StableCrateId) -> PathBuf { +fn crate_path(sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId) -> PathBuf { let incr_dir = sess.opts.incremental.as_ref().unwrap().clone(); let stable_crate_id = base_n::encode(stable_crate_id.to_u64() as u128, INT_ENCODE_BASE); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 3256ca1fb20..987559d7e47 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -56,22 +56,17 @@ use crate::infer::ExpectedFound; use crate::traits::error_reporting::report_object_safety_error; use crate::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, - StatementAsExpression, }; -use crate::errors::SuggAddLetForLetChains; -use hir::intravisit::{walk_expr, walk_stmt}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan}; use rustc_hir as hir; -use rustc_hir::def::{CtorKind, DefKind}; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::Node; use rustc_middle::dep_graph::DepContext; -use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::relate::{self, RelateResult, TypeRelation}; use rustc_middle::ty::{ self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, @@ -80,9 +75,11 @@ use rustc_middle::ty::{ use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; use std::ops::{ControlFlow, Deref}; +use std::path::PathBuf; use std::{cmp, fmt, iter}; mod note; +mod suggest; pub(crate) mod need_type_info; pub use need_type_info::TypeAnnotationNeeded; @@ -806,87 +803,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - fn suggest_remove_semi_or_return_binding( - &self, - err: &mut Diagnostic, - first_id: Option<hir::HirId>, - first_ty: Ty<'tcx>, - first_span: Span, - second_id: Option<hir::HirId>, - second_ty: Ty<'tcx>, - second_span: Span, - ) { - let remove_semicolon = [ - (first_id, self.resolve_vars_if_possible(second_ty)), - (second_id, self.resolve_vars_if_possible(first_ty)), - ] - .into_iter() - .find_map(|(id, ty)| { - let hir::Node::Block(blk) = self.tcx.hir().get(id?) else { return None }; - self.could_remove_semicolon(blk, ty) - }); - match remove_semicolon { - Some((sp, StatementAsExpression::NeedsBoxing)) => { - err.multipart_suggestion( - "consider removing this semicolon and boxing the expressions", - vec![ - (first_span.shrink_to_lo(), "Box::new(".to_string()), - (first_span.shrink_to_hi(), ")".to_string()), - (second_span.shrink_to_lo(), "Box::new(".to_string()), - (second_span.shrink_to_hi(), ")".to_string()), - (sp, String::new()), - ], - Applicability::MachineApplicable, - ); - } - Some((sp, StatementAsExpression::CorrectType)) => { - err.span_suggestion_short( - sp, - "consider removing this semicolon", - "", - Applicability::MachineApplicable, - ); - } - None => { - for (id, ty) in [(first_id, second_ty), (second_id, first_ty)] { - if let Some(id) = id - && let hir::Node::Block(blk) = self.tcx.hir().get(id) - && self.consider_returning_binding(blk, ty, err) - { - break; - } - } - } - } - } - - fn suggest_boxing_for_return_impl_trait( - &self, - err: &mut Diagnostic, - return_sp: Span, - arm_spans: impl Iterator<Item = Span>, - ) { - err.multipart_suggestion( - "you could change the return type to be a boxed trait object", - vec![ - (return_sp.with_hi(return_sp.lo() + BytePos(4)), "Box<dyn".to_string()), - (return_sp.shrink_to_hi(), ">".to_string()), - ], - Applicability::MaybeIncorrect, - ); - let sugg = arm_spans - .flat_map(|sp| { - [(sp.shrink_to_lo(), "Box::new(".to_string()), (sp.shrink_to_hi(), ")".to_string())] - .into_iter() - }) - .collect::<Vec<_>>(); - err.multipart_suggestion( - "if you change the return type to expect trait objects, box the returned expressions", - sugg, - Applicability::MaybeIncorrect, - ); - } - /// Given that `other_ty` is the same as a type argument for `name` in `sub`, populate `value` /// highlighting `name` and every type argument that isn't at `pos` (which is `other_ty`), and /// populate `other_value` with `other_ty`. @@ -1352,10 +1268,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .map(|(mod_str, _)| mod_str.len() + separator_len) .sum(); - debug!( - "cmp: separator_len={}, split_idx={}, min_len={}", - separator_len, split_idx, min_len - ); + debug!(?separator_len, ?split_idx, ?min_len, "cmp"); if split_idx >= min_len { // paths are identical, highlight everything @@ -1366,7 +1279,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } else { let (common, uniq1) = t1_str.split_at(split_idx); let (_, uniq2) = t2_str.split_at(split_idx); - debug!("cmp: common={}, uniq1={}, uniq2={}", common, uniq1, uniq2); + debug!(?common, ?uniq1, ?uniq2, "cmp"); values.0.push_normal(common); values.0.push_highlighted(uniq1); @@ -1659,17 +1572,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")), }; - let vals = match self.values_str(values) { - Some((expected, found)) => Some((expected, found)), - None => { - // Derived error. Cancel the emitter. - // NOTE(eddyb) this was `.cancel()`, but `diag` - // is borrowed, so we can't fully defuse it. - diag.downgrade_to_delayed_bug(); - return; - } + let Some(vals) = self.values_str(values) else { + // Derived error. Cancel the emitter. + // NOTE(eddyb) this was `.cancel()`, but `diag` + // is borrowed, so we can't fully defuse it. + diag.downgrade_to_delayed_bug(); + return; }; - (vals, exp_found, is_simple_error, Some(values)) + (Some(vals), exp_found, is_simple_error, Some(values)) } }; @@ -1701,7 +1611,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { label_or_note(span, &terr.to_string()); } - if let Some((expected, found)) = expected_found { + if let Some((expected, found, exp_p, found_p)) = expected_found { let (expected_label, found_label, exp_found) = match exp_found { Mismatch::Variable(ef) => ( ef.expected.prefix_string(self.tcx), @@ -1818,32 +1728,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } TypeError::Sorts(values) => { let extra = expected == found; - let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) { - (true, ty::Opaque(def_id, _)) => { - let sm = self.tcx.sess.source_map(); - let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo()); - format!( - " (opaque type at <{}:{}:{}>)", - sm.filename_for_diagnostics(&pos.file.name), - pos.line, - pos.col.to_usize() + 1, - ) - } - (true, ty::Projection(proj)) - if self.tcx.def_kind(proj.item_def_id) - == DefKind::ImplTraitPlaceholder => - { - let sm = self.tcx.sess.source_map(); - let pos = sm.lookup_char_pos(self.tcx.def_span(proj.item_def_id).lo()); - format!( - " (trait associated opaque type at <{}:{}:{}>)", - sm.filename_for_diagnostics(&pos.file.name), - pos.line, - pos.col.to_usize() + 1, - ) + let sort_string = |ty: Ty<'tcx>, path: Option<PathBuf>| { + let mut s = match (extra, ty.kind()) { + (true, ty::Opaque(def_id, _)) => { + let sm = self.tcx.sess.source_map(); + let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo()); + format!( + " (opaque type at <{}:{}:{}>)", + sm.filename_for_diagnostics(&pos.file.name), + pos.line, + pos.col.to_usize() + 1, + ) + } + (true, ty::Projection(proj)) + if self.tcx.def_kind(proj.item_def_id) + == DefKind::ImplTraitPlaceholder => + { + let sm = self.tcx.sess.source_map(); + let pos = sm.lookup_char_pos(self.tcx.def_span(proj.item_def_id).lo()); + format!( + " (trait associated opaque type at <{}:{}:{}>)", + sm.filename_for_diagnostics(&pos.file.name), + pos.line, + pos.col.to_usize() + 1, + ) + } + (true, _) => format!(" ({})", ty.sort_string(self.tcx)), + (false, _) => "".to_string(), + }; + if let Some(path) = path { + s.push_str(&format!( + "\nthe full type name has been written to '{}'", + path.display(), + )); } - (true, _) => format!(" ({})", ty.sort_string(self.tcx)), - (false, _) => "".to_string(), + s }; if !(values.expected.is_simple_text() && values.found.is_simple_text()) || (exp_found.map_or(false, |ef| { @@ -1865,8 +1784,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { expected, &found_label, found, - &sort_string(values.expected), - &sort_string(values.found), + &sort_string(values.expected, exp_p), + &sort_string(values.found, found_p), ); } } @@ -1940,310 +1859,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { debug!(?diag); } - fn suggest_tuple_pattern( - &self, - cause: &ObligationCause<'tcx>, - exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, - diag: &mut Diagnostic, - ) { - // Heavily inspired by `FnCtxt::suggest_compatible_variants`, with - // some modifications due to that being in typeck and this being in infer. - if let ObligationCauseCode::Pattern { .. } = cause.code() { - if let ty::Adt(expected_adt, substs) = exp_found.expected.kind() { - let compatible_variants: Vec<_> = expected_adt - .variants() - .iter() - .filter(|variant| { - variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn) - }) - .filter_map(|variant| { - let sole_field = &variant.fields[0]; - let sole_field_ty = sole_field.ty(self.tcx, substs); - if self.same_type_modulo_infer(sole_field_ty, exp_found.found) { - let variant_path = - with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id)); - // FIXME #56861: DRYer prelude filtering - if let Some(path) = variant_path.strip_prefix("std::prelude::") { - if let Some((_, path)) = path.split_once("::") { - return Some(path.to_string()); - } - } - Some(variant_path) - } else { - None - } - }) - .collect(); - match &compatible_variants[..] { - [] => {} - [variant] => { - diag.multipart_suggestion_verbose( - &format!("try wrapping the pattern in `{}`", variant), - vec![ - (cause.span.shrink_to_lo(), format!("{}(", variant)), - (cause.span.shrink_to_hi(), ")".to_string()), - ], - Applicability::MaybeIncorrect, - ); - } - _ => { - // More than one matching variant. - diag.multipart_suggestions( - &format!( - "try wrapping the pattern in a variant of `{}`", - self.tcx.def_path_str(expected_adt.did()) - ), - compatible_variants.into_iter().map(|variant| { - vec![ - (cause.span.shrink_to_lo(), format!("{}(", variant)), - (cause.span.shrink_to_hi(), ")".to_string()), - ] - }), - Applicability::MaybeIncorrect, - ); - } - } - } - } - } - - /// A possible error is to forget to add `.await` when using futures: - /// - /// ```compile_fail,E0308 - /// async fn make_u32() -> u32 { - /// 22 - /// } - /// - /// fn take_u32(x: u32) {} - /// - /// async fn foo() { - /// let x = make_u32(); - /// take_u32(x); - /// } - /// ``` - /// - /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the - /// expected type. If this is the case, and we are inside of an async body, it suggests adding - /// `.await` to the tail of the expression. - fn suggest_await_on_expect_found( - &self, - cause: &ObligationCause<'tcx>, - exp_span: Span, - exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, - diag: &mut Diagnostic, - ) { - debug!( - "suggest_await_on_expect_found: exp_span={:?}, expected_ty={:?}, found_ty={:?}", - exp_span, exp_found.expected, exp_found.found, - ); - - if let ObligationCauseCode::CompareImplItemObligation { .. } = cause.code() { - return; - } - - match ( - self.get_impl_future_output_ty(exp_found.expected), - self.get_impl_future_output_ty(exp_found.found), - ) { - (Some(exp), Some(found)) if self.same_type_modulo_infer(exp, found) => match cause - .code() - { - ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { - let then_span = self.find_block_span_from_hir_id(*then_id); - diag.multipart_suggestion( - "consider `await`ing on both `Future`s", - vec![ - (then_span.shrink_to_hi(), ".await".to_string()), - (exp_span.shrink_to_hi(), ".await".to_string()), - ], - Applicability::MaybeIncorrect, - ); - } - ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { - prior_arms, - .. - }) => { - if let [.., arm_span] = &prior_arms[..] { - diag.multipart_suggestion( - "consider `await`ing on both `Future`s", - vec![ - (arm_span.shrink_to_hi(), ".await".to_string()), - (exp_span.shrink_to_hi(), ".await".to_string()), - ], - Applicability::MaybeIncorrect, - ); - } else { - diag.help("consider `await`ing on both `Future`s"); - } - } - _ => { - diag.help("consider `await`ing on both `Future`s"); - } - }, - (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { - diag.span_suggestion_verbose( - exp_span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await", - Applicability::MaybeIncorrect, - ); - } - (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() - { - ObligationCauseCode::Pattern { span: Some(then_span), .. } => { - diag.span_suggestion_verbose( - then_span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await", - Applicability::MaybeIncorrect, - ); - } - ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { - let then_span = self.find_block_span_from_hir_id(*then_id); - diag.span_suggestion_verbose( - then_span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await", - Applicability::MaybeIncorrect, - ); - } - ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { - ref prior_arms, - .. - }) => { - diag.multipart_suggestion_verbose( - "consider `await`ing on the `Future`", - prior_arms - .iter() - .map(|arm| (arm.shrink_to_hi(), ".await".to_string())) - .collect(), - Applicability::MaybeIncorrect, - ); - } - _ => {} - }, - _ => {} - } - } - - fn suggest_accessing_field_where_appropriate( - &self, - cause: &ObligationCause<'tcx>, - exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, - diag: &mut Diagnostic, - ) { - debug!( - "suggest_accessing_field_where_appropriate(cause={:?}, exp_found={:?})", - cause, exp_found - ); - if let ty::Adt(expected_def, expected_substs) = exp_found.expected.kind() { - if expected_def.is_enum() { - return; - } - - if let Some((name, ty)) = expected_def - .non_enum_variant() - .fields - .iter() - .filter(|field| field.vis.is_accessible_from(field.did, self.tcx)) - .map(|field| (field.name, field.ty(self.tcx, expected_substs))) - .find(|(_, ty)| self.same_type_modulo_infer(*ty, exp_found.found)) - { - if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - let suggestion = if expected_def.is_struct() { - format!("{}.{}", snippet, name) - } else if expected_def.is_union() { - format!("unsafe {{ {}.{} }}", snippet, name) - } else { - return; - }; - diag.span_suggestion( - span, - &format!( - "you might have meant to use field `{}` whose type is `{}`", - name, ty - ), - suggestion, - Applicability::MaybeIncorrect, - ); - } - } - } - } - } - - /// When encountering a case where `.as_ref()` on a `Result` or `Option` would be appropriate, - /// suggests it. - fn suggest_as_ref_where_appropriate( - &self, - span: Span, - exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, - diag: &mut Diagnostic, - ) { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) - && let Some(msg) = self.should_suggest_as_ref(exp_found.expected, exp_found.found) - { - diag.span_suggestion( - span, - msg, - // HACK: fix issue# 100605, suggesting convert from &Option<T> to Option<&T>, remove the extra `&` - format!("{}.as_ref()", snippet.trim_start_matches('&')), - Applicability::MachineApplicable, - ); - } - } - - pub fn should_suggest_as_ref(&self, expected: Ty<'tcx>, found: Ty<'tcx>) -> Option<&str> { - if let (ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) = - (expected.kind(), found.kind()) - { - if let ty::Adt(found_def, found_substs) = *found_ty.kind() { - if exp_def == &found_def { - let have_as_ref = &[ - ( - sym::Option, - "you can convert from `&Option<T>` to `Option<&T>` using \ - `.as_ref()`", - ), - ( - sym::Result, - "you can convert from `&Result<T, E>` to \ - `Result<&T, &E>` using `.as_ref()`", - ), - ]; - if let Some(msg) = have_as_ref.iter().find_map(|(name, msg)| { - self.tcx.is_diagnostic_item(*name, exp_def.did()).then_some(msg) - }) { - let mut show_suggestion = true; - for (exp_ty, found_ty) in - iter::zip(exp_substs.types(), found_substs.types()) - { - match *exp_ty.kind() { - ty::Ref(_, exp_ty, _) => { - match (exp_ty.kind(), found_ty.kind()) { - (_, ty::Param(_)) - | (_, ty::Infer(_)) - | (ty::Param(_), _) - | (ty::Infer(_), _) => {} - _ if self.same_type_modulo_infer(exp_ty, found_ty) => {} - _ => show_suggestion = false, - }; - } - ty::Param(_) | ty::Infer(_) => {} - _ => show_suggestion = false, - } - } - if show_suggestion { - return Some(*msg); - } - } - } - } - } - None - } - pub fn report_and_explain_type_error( &self, trace: TypeTrace<'tcx>, @@ -2339,7 +1954,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let code = trace.cause.code(); if let &MatchExpressionArm(box MatchExpressionArmCause { source, .. }) = code && let hir::MatchSource::TryDesugar = source - && let Some((expected_ty, found_ty)) = self.values_str(trace.values) + && let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values) { err.note(&format!( "`?` operator cannot convert from `{}` to `{}`", @@ -2357,67 +1972,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag } - /// Try to find code with pattern `if Some(..) = expr` - /// use a `visitor` to mark the `if` which its span contains given error span, - /// and then try to find a assignment in the `cond` part, which span is equal with error span - fn suggest_let_for_letchains( - &self, - err: &mut Diagnostic, - cause: &ObligationCause<'_>, - span: Span, - ) { - let hir = self.tcx.hir(); - let fn_hir_id = hir.get_parent_node(cause.body_id); - if let Some(node) = self.tcx.hir().find(fn_hir_id) && - let hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn(_sig, _, body_id), .. - }) = node { - let body = hir.body(*body_id); - - /// Find the if expression with given span - struct IfVisitor { - pub result: bool, - pub found_if: bool, - pub err_span: Span, - } - - impl<'v> Visitor<'v> for IfVisitor { - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - if self.result { return; } - match ex.kind { - hir::ExprKind::If(cond, _, _) => { - self.found_if = true; - walk_expr(self, cond); - self.found_if = false; - } - _ => walk_expr(self, ex), - } - } - - fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) { - if let hir::StmtKind::Local(hir::Local { - span, pat: hir::Pat{..}, ty: None, init: Some(_), .. - }) = &ex.kind - && self.found_if - && span.eq(&self.err_span) { - self.result = true; - } - walk_stmt(self, ex); - } - - fn visit_body(&mut self, body: &'v hir::Body<'v>) { - hir::intravisit::walk_body(self, body); - } - } - - let mut visitor = IfVisitor { err_span: span, found_if: false, result: false }; - visitor.visit_body(&body); - if visitor.result { - err.subdiagnostic(SuggAddLetForLetChains{span: span.shrink_to_lo()}); - } - } - } - fn emit_tuple_wrap_err( &self, err: &mut Diagnostic, @@ -2455,7 +2009,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn values_str( &self, values: ValuePairs<'tcx>, - ) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> { + ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)> + { match values { infer::Regions(exp_found) => self.expected_found_str(exp_found), infer::Terms(exp_found) => self.expected_found_str_term(exp_found), @@ -2465,7 +2020,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { found: exp_found.found.print_only_trait_path(), }; match self.expected_found_str(pretty_exp_found) { - Some((expected, found)) if expected == found => { + Some((expected, found, _, _)) if expected == found => { self.expected_found_str(exp_found) } ret => ret, @@ -2477,7 +2032,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { found: exp_found.found.print_only_trait_path(), }; match self.expected_found_str(pretty_exp_found) { - Some((expected, found)) if expected == found => { + Some((expected, found, _, _)) if expected == found => { self.expected_found_str(exp_found) } ret => ret, @@ -2489,17 +2044,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn expected_found_str_term( &self, exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>, - ) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> { + ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)> + { let exp_found = self.resolve_vars_if_possible(exp_found); if exp_found.references_error() { return None; } Some(match (exp_found.expected.unpack(), exp_found.found.unpack()) { - (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => self.cmp(expected, found), + (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => { + let (mut exp, mut fnd) = self.cmp(expected, found); + // Use the terminal width as the basis to determine when to compress the printed + // out type, but give ourselves some leeway to avoid ending up creating a file for + // a type that is somewhat shorter than the path we'd write to. + let len = self.tcx.sess().diagnostic_width() + 40; + let exp_s = exp.content(); + let fnd_s = fnd.content(); + let mut exp_p = None; + let mut fnd_p = None; + if exp_s.len() > len { + let (exp_s, exp_path) = self.tcx.short_ty_string(expected); + exp = DiagnosticStyledString::highlighted(exp_s); + exp_p = exp_path; + } + if fnd_s.len() > len { + let (fnd_s, fnd_path) = self.tcx.short_ty_string(found); + fnd = DiagnosticStyledString::highlighted(fnd_s); + fnd_p = fnd_path; + } + (exp, fnd, exp_p, fnd_p) + } _ => ( DiagnosticStyledString::highlighted(exp_found.expected.to_string()), DiagnosticStyledString::highlighted(exp_found.found.to_string()), + None, + None, ), }) } @@ -2508,7 +2087,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn expected_found_str<T: fmt::Display + TypeFoldable<'tcx>>( &self, exp_found: ty::error::ExpectedFound<T>, - ) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> { + ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)> + { let exp_found = self.resolve_vars_if_possible(exp_found); if exp_found.references_error() { return None; @@ -2517,6 +2097,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { Some(( DiagnosticStyledString::highlighted(exp_found.expected.to_string()), DiagnosticStyledString::highlighted(exp_found.found.to_string()), + None, + None, )) } @@ -2850,36 +2432,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { debug!("report_sub_sup_conflict: sup_region={:?}", sup_region); debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin); - if let (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) = - (&sup_origin, &sub_origin) + if let infer::Subtype(ref sup_trace) = sup_origin + && let infer::Subtype(ref sub_trace) = sub_origin + && let Some((sup_expected, sup_found, _, _)) = self.values_str(sup_trace.values) + && let Some((sub_expected, sub_found, _, _)) = self.values_str(sub_trace.values) + && sub_expected == sup_expected + && sub_found == sup_found { - debug!("report_sub_sup_conflict: sup_trace={:?}", sup_trace); - debug!("report_sub_sup_conflict: sub_trace={:?}", sub_trace); - debug!("report_sub_sup_conflict: sup_trace.values={:?}", sup_trace.values); - debug!("report_sub_sup_conflict: sub_trace.values={:?}", sub_trace.values); - - if let (Some((sup_expected, sup_found)), Some((sub_expected, sub_found))) = - (self.values_str(sup_trace.values), self.values_str(sub_trace.values)) - { - if sub_expected == sup_expected && sub_found == sup_found { - note_and_explain_region( - self.tcx, - &mut err, - "...but the lifetime must also be valid for ", - sub_region, - "...", - None, - ); - err.span_note( - sup_trace.cause.span, - &format!("...so that the {}", sup_trace.cause.as_requirement_str()), - ); + note_and_explain_region( + self.tcx, + &mut err, + "...but the lifetime must also be valid for ", + sub_region, + "...", + None, + ); + err.span_note( + sup_trace.cause.span, + &format!("...so that the {}", sup_trace.cause.as_requirement_str()), + ); - err.note_expected_found(&"", sup_expected, &"", sup_found); - err.emit(); - return; - } - } + err.note_expected_found(&"", sup_expected, &"", sup_found); + err.emit(); + return; } self.note_region_origin(&mut err, &sup_origin); @@ -3228,211 +2803,3 @@ impl<'tcx> InferCtxt<'tcx> { } } } - -impl<'tcx> TypeErrCtxt<'_, 'tcx> { - /// Be helpful when the user wrote `{... expr; }` and taking the `;` off - /// is enough to fix the error. - pub fn could_remove_semicolon( - &self, - blk: &'tcx hir::Block<'tcx>, - expected_ty: Ty<'tcx>, - ) -> Option<(Span, StatementAsExpression)> { - let blk = blk.innermost_block(); - // Do not suggest if we have a tail expr. - if blk.expr.is_some() { - return None; - } - let last_stmt = blk.stmts.last()?; - let hir::StmtKind::Semi(ref last_expr) = last_stmt.kind else { - return None; - }; - let last_expr_ty = self.typeck_results.as_ref()?.expr_ty_opt(*last_expr)?; - let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) { - _ if last_expr_ty.references_error() => return None, - _ if self.same_type_modulo_infer(last_expr_ty, expected_ty) => { - StatementAsExpression::CorrectType - } - (ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _)) - if last_def_id == exp_def_id => - { - StatementAsExpression::CorrectType - } - (ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => { - debug!( - "both opaque, likely future {:?} {:?} {:?} {:?}", - last_def_id, last_bounds, exp_def_id, exp_bounds - ); - - let last_local_id = last_def_id.as_local()?; - let exp_local_id = exp_def_id.as_local()?; - - match ( - &self.tcx.hir().expect_item(last_local_id).kind, - &self.tcx.hir().expect_item(exp_local_id).kind, - ) { - ( - hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }), - hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }), - ) if iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| { - match (left, right) { - ( - hir::GenericBound::Trait(tl, ml), - hir::GenericBound::Trait(tr, mr), - ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() - && ml == mr => - { - true - } - ( - hir::GenericBound::LangItemTrait(langl, _, _, argsl), - hir::GenericBound::LangItemTrait(langr, _, _, argsr), - ) if langl == langr => { - // FIXME: consider the bounds! - debug!("{:?} {:?}", argsl, argsr); - true - } - _ => false, - } - }) => - { - StatementAsExpression::NeedsBoxing - } - _ => StatementAsExpression::CorrectType, - } - } - _ => return None, - }; - let span = if last_stmt.span.from_expansion() { - let mac_call = rustc_span::source_map::original_sp(last_stmt.span, blk.span); - self.tcx.sess.source_map().mac_call_stmt_semi_span(mac_call)? - } else { - last_stmt.span.with_lo(last_stmt.span.hi() - BytePos(1)) - }; - Some((span, needs_box)) - } - - /// Suggest returning a local binding with a compatible type if the block - /// has no return expression. - pub fn consider_returning_binding( - &self, - blk: &'tcx hir::Block<'tcx>, - expected_ty: Ty<'tcx>, - err: &mut Diagnostic, - ) -> bool { - let blk = blk.innermost_block(); - // Do not suggest if we have a tail expr. - if blk.expr.is_some() { - return false; - } - let mut shadowed = FxIndexSet::default(); - let mut candidate_idents = vec![]; - let mut find_compatible_candidates = |pat: &hir::Pat<'_>| { - if let hir::PatKind::Binding(_, hir_id, ident, _) = &pat.kind - && let Some(pat_ty) = self - .typeck_results - .as_ref() - .and_then(|typeck_results| typeck_results.node_type_opt(*hir_id)) - { - let pat_ty = self.resolve_vars_if_possible(pat_ty); - if self.same_type_modulo_infer(pat_ty, expected_ty) - && !(pat_ty, expected_ty).references_error() - && shadowed.insert(ident.name) - { - candidate_idents.push((*ident, pat_ty)); - } - } - true - }; - - let hir = self.tcx.hir(); - for stmt in blk.stmts.iter().rev() { - let hir::StmtKind::Local(local) = &stmt.kind else { continue; }; - local.pat.walk(&mut find_compatible_candidates); - } - match hir.find(hir.get_parent_node(blk.hir_id)) { - Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => { - match hir.find(hir.get_parent_node(*hir_id)) { - Some(hir::Node::Arm(hir::Arm { pat, .. })) => { - pat.walk(&mut find_compatible_candidates); - } - Some( - hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. }) - | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Fn(_, body), - .. - }) - | hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)), - .. - }) - | hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(hir::Closure { body, .. }), - .. - }), - ) => { - for param in hir.body(*body).params { - param.pat.walk(&mut find_compatible_candidates); - } - } - Some(hir::Node::Expr(hir::Expr { - kind: - hir::ExprKind::If( - hir::Expr { kind: hir::ExprKind::Let(let_), .. }, - then_block, - _, - ), - .. - })) if then_block.hir_id == *hir_id => { - let_.pat.walk(&mut find_compatible_candidates); - } - _ => {} - } - } - _ => {} - } - - match &candidate_idents[..] { - [(ident, _ty)] => { - let sm = self.tcx.sess.source_map(); - if let Some(stmt) = blk.stmts.last() { - let stmt_span = sm.stmt_span(stmt.span, blk.span); - let sugg = if sm.is_multiline(blk.span) - && let Some(spacing) = sm.indentation_before(stmt_span) - { - format!("\n{spacing}{ident}") - } else { - format!(" {ident}") - }; - err.span_suggestion_verbose( - stmt_span.shrink_to_hi(), - format!("consider returning the local binding `{ident}`"), - sugg, - Applicability::MaybeIncorrect, - ); - } else { - let sugg = if sm.is_multiline(blk.span) - && let Some(spacing) = sm.indentation_before(blk.span.shrink_to_lo()) - { - format!("\n{spacing} {ident}\n{spacing}") - } else { - format!(" {ident} ") - }; - let left_span = sm.span_through_char(blk.span, '{').shrink_to_hi(); - err.span_suggestion_verbose( - sm.span_extend_while(left_span, |c| c.is_whitespace()).unwrap_or(left_span), - format!("consider returning the local binding `{ident}`"), - sugg, - Applicability::MaybeIncorrect, - ); - } - true - } - values if (1..3).contains(&values.len()) => { - let spans = values.iter().map(|(ident, _)| ident.span).collect::<Vec<_>>(); - err.span_note(spans, "consider returning one of these bindings"); - true - } - _ => false, - } - } -} diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 41b115f3377..d2dffa4a0b7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -16,7 +16,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { span: trace.cause.span, requirement: ObligationCauseAsDiagArg(trace.cause.clone()), - expected_found: self.values_str(trace.values), + expected_found: self.values_str(trace.values).map(|(e, f, _, _)| (e, f)), } .add_to_diagnostic(err), infer::Reborrow(span) => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_region.rs b/compiler/rustc_infer/src/infer/error_reporting/note_region.rs new file mode 100644 index 00000000000..41b115f3377 --- /dev/null +++ b/compiler/rustc_infer/src/infer/error_reporting/note_region.rs @@ -0,0 +1,427 @@ +use crate::errors::RegionOriginNote; +use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; +use crate::infer::{self, SubregionOrigin}; +use rustc_errors::{ + fluent, struct_span_err, AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, +}; +use rustc_middle::traits::ObligationCauseCode; +use rustc_middle::ty::error::TypeError; +use rustc_middle::ty::{self, Region}; + +use super::ObligationCauseAsDiagArg; + +impl<'tcx> TypeErrCtxt<'_, 'tcx> { + pub(super) fn note_region_origin(&self, err: &mut Diagnostic, origin: &SubregionOrigin<'tcx>) { + match *origin { + infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { + span: trace.cause.span, + requirement: ObligationCauseAsDiagArg(trace.cause.clone()), + expected_found: self.values_str(trace.values), + } + .add_to_diagnostic(err), + infer::Reborrow(span) => { + RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diagnostic(err) + } + infer::ReborrowUpvar(span, ref upvar_id) => { + let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); + RegionOriginNote::WithName { + span, + msg: fluent::infer_reborrow, + name: &var_name.to_string(), + continues: false, + } + .add_to_diagnostic(err); + } + infer::RelateObjectBound(span) => { + RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound } + .add_to_diagnostic(err); + } + infer::DataBorrowed(ty, span) => { + RegionOriginNote::WithName { + span, + msg: fluent::infer_data_borrowed, + name: &self.ty_to_string(ty), + continues: false, + } + .add_to_diagnostic(err); + } + infer::ReferenceOutlivesReferent(ty, span) => { + RegionOriginNote::WithName { + span, + msg: fluent::infer_reference_outlives_referent, + name: &self.ty_to_string(ty), + continues: false, + } + .add_to_diagnostic(err); + } + infer::RelateParamBound(span, ty, opt_span) => { + RegionOriginNote::WithName { + span, + msg: fluent::infer_relate_param_bound, + name: &self.ty_to_string(ty), + continues: opt_span.is_some(), + } + .add_to_diagnostic(err); + if let Some(span) = opt_span { + RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 } + .add_to_diagnostic(err); + } + } + infer::RelateRegionParamBound(span) => { + RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound } + .add_to_diagnostic(err); + } + infer::CompareImplItemObligation { span, .. } => { + RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation } + .add_to_diagnostic(err); + } + infer::CheckAssociatedTypeBounds { ref parent, .. } => { + self.note_region_origin(err, &parent); + } + infer::AscribeUserTypeProvePredicate(span) => { + RegionOriginNote::Plain { + span, + msg: fluent::infer_ascribe_user_type_prove_predicate, + } + .add_to_diagnostic(err); + } + } + } + + pub(super) fn report_concrete_failure( + &self, + origin: SubregionOrigin<'tcx>, + sub: Region<'tcx>, + sup: Region<'tcx>, + ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { + match origin { + infer::Subtype(box trace) => { + let terr = TypeError::RegionsDoesNotOutlive(sup, sub); + let mut err = self.report_and_explain_type_error(trace, terr); + match (*sub, *sup) { + (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {} + (ty::RePlaceholder(_), _) => { + note_and_explain_region( + self.tcx, + &mut err, + "", + sup, + " doesn't meet the lifetime requirements", + None, + ); + } + (_, ty::RePlaceholder(_)) => { + note_and_explain_region( + self.tcx, + &mut err, + "the required lifetime does not necessarily outlive ", + sub, + "", + None, + ); + } + _ => { + note_and_explain_region(self.tcx, &mut err, "", sup, "...", None); + note_and_explain_region( + self.tcx, + &mut err, + "...does not necessarily outlive ", + sub, + "", + None, + ); + } + } + err + } + infer::Reborrow(span) => { + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0312, + "lifetime of reference outlives lifetime of borrowed content..." + ); + note_and_explain_region( + self.tcx, + &mut err, + "...the reference is valid for ", + sub, + "...", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + "...but the borrowed content is only valid for ", + sup, + "", + None, + ); + err + } + infer::ReborrowUpvar(span, ref upvar_id) => { + let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0313, + "lifetime of borrowed pointer outlives lifetime of captured variable `{}`...", + var_name + ); + note_and_explain_region( + self.tcx, + &mut err, + "...the borrowed pointer is valid for ", + sub, + "...", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + &format!("...but `{}` is only valid for ", var_name), + sup, + "", + None, + ); + err + } + infer::RelateObjectBound(span) => { + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0476, + "lifetime of the source pointer does not outlive lifetime bound of the \ + object type" + ); + note_and_explain_region( + self.tcx, + &mut err, + "object type is valid for ", + sub, + "", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + "source pointer is only valid for ", + sup, + "", + None, + ); + err + } + infer::RelateParamBound(span, ty, opt_span) => { + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0477, + "the type `{}` does not fulfill the required lifetime", + self.ty_to_string(ty) + ); + match *sub { + ty::ReStatic => note_and_explain_region( + self.tcx, + &mut err, + "type must satisfy ", + sub, + if opt_span.is_some() { " as required by this binding" } else { "" }, + opt_span, + ), + _ => note_and_explain_region( + self.tcx, + &mut err, + "type must outlive ", + sub, + if opt_span.is_some() { " as required by this binding" } else { "" }, + opt_span, + ), + } + err + } + infer::RelateRegionParamBound(span) => { + let mut err = + struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); + note_and_explain_region( + self.tcx, + &mut err, + "lifetime parameter instantiated with ", + sup, + "", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + "but lifetime parameter must outlive ", + sub, + "", + None, + ); + err + } + infer::DataBorrowed(ty, span) => { + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0490, + "a value of type `{}` is borrowed for too long", + self.ty_to_string(ty) + ); + note_and_explain_region( + self.tcx, + &mut err, + "the type is valid for ", + sub, + "", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + "but the borrow lasts for ", + sup, + "", + None, + ); + err + } + infer::ReferenceOutlivesReferent(ty, span) => { + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0491, + "in type `{}`, reference has a longer lifetime than the data it references", + self.ty_to_string(ty) + ); + note_and_explain_region( + self.tcx, + &mut err, + "the pointer is valid for ", + sub, + "", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + "but the referenced data is only valid for ", + sup, + "", + None, + ); + err + } + infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => self + .report_extra_impl_obligation( + span, + impl_item_def_id, + trait_item_def_id, + &format!("`{}: {}`", sup, sub), + ), + infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { + let mut err = self.report_concrete_failure(*parent, sub, sup); + + let trait_item_span = self.tcx.def_span(trait_item_def_id); + let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); + err.span_label( + trait_item_span, + format!("definition of `{}` from trait", item_name), + ); + + let trait_predicates = self.tcx.explicit_predicates_of(trait_item_def_id); + let impl_predicates = self.tcx.explicit_predicates_of(impl_item_def_id); + + let impl_predicates: rustc_data_structures::fx::FxHashSet<_> = + impl_predicates.predicates.into_iter().map(|(pred, _)| pred).collect(); + let clauses: Vec<_> = trait_predicates + .predicates + .into_iter() + .filter(|&(pred, _)| !impl_predicates.contains(pred)) + .map(|(pred, _)| format!("{}", pred)) + .collect(); + + if !clauses.is_empty() { + let generics = self.tcx.hir().get_generics(impl_item_def_id).unwrap(); + let where_clause_span = generics.tail_span_for_predicate_suggestion(); + + let suggestion = format!( + "{} {}", + generics.add_where_or_trailing_comma(), + clauses.join(", "), + ); + err.span_suggestion( + where_clause_span, + &format!( + "try copying {} from the trait", + if clauses.len() > 1 { "these clauses" } else { "this clause" } + ), + suggestion, + rustc_errors::Applicability::MaybeIncorrect, + ); + } + + err + } + infer::AscribeUserTypeProvePredicate(span) => { + let mut err = + struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); + note_and_explain_region( + self.tcx, + &mut err, + "lifetime instantiated with ", + sup, + "", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + "but lifetime must outlive ", + sub, + "", + None, + ); + err + } + } + } + + pub(super) fn report_placeholder_failure( + &self, + placeholder_origin: SubregionOrigin<'tcx>, + sub: Region<'tcx>, + sup: Region<'tcx>, + ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { + // I can't think how to do better than this right now. -nikomatsakis + debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); + match placeholder_origin { + infer::Subtype(box ref trace) + if matches!( + &trace.cause.code().peel_derives(), + ObligationCauseCode::BindingObligation(..) + | ObligationCauseCode::ExprBindingObligation(..) + ) => + { + // Hack to get around the borrow checker because trace.cause has an `Rc`. + if let ObligationCauseCode::BindingObligation(_, span) + | ObligationCauseCode::ExprBindingObligation(_, span, ..) = + &trace.cause.code().peel_derives() + { + let span = *span; + let mut err = self.report_concrete_failure(placeholder_origin, sub, sup); + err.span_note(span, "the lifetime requirement is introduced here"); + err + } else { + unreachable!() + } + } + infer::Subtype(box trace) => { + let terr = TypeError::RegionsPlaceholderMismatch; + return self.report_and_explain_type_error(trace, terr); + } + _ => return self.report_concrete_failure(placeholder_origin, sub, sup), + } + } +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs new file mode 100644 index 00000000000..73b5a2cc4ad --- /dev/null +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -0,0 +1,672 @@ +use hir::def::CtorKind; +use hir::intravisit::{walk_expr, walk_stmt, Visitor}; +use rustc_data_structures::fx::FxIndexSet; +use rustc_errors::{Applicability, Diagnostic}; +use rustc_hir as hir; +use rustc_middle::traits::{ + IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, + StatementAsExpression, +}; +use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::{self as ty, Ty, TypeVisitable}; +use rustc_span::{sym, BytePos, Span}; + +use crate::errors::SuggAddLetForLetChains; + +use super::TypeErrCtxt; + +impl<'tcx> TypeErrCtxt<'_, 'tcx> { + pub(super) fn suggest_remove_semi_or_return_binding( + &self, + err: &mut Diagnostic, + first_id: Option<hir::HirId>, + first_ty: Ty<'tcx>, + first_span: Span, + second_id: Option<hir::HirId>, + second_ty: Ty<'tcx>, + second_span: Span, + ) { + let remove_semicolon = [ + (first_id, self.resolve_vars_if_possible(second_ty)), + (second_id, self.resolve_vars_if_possible(first_ty)), + ] + .into_iter() + .find_map(|(id, ty)| { + let hir::Node::Block(blk) = self.tcx.hir().get(id?) else { return None }; + self.could_remove_semicolon(blk, ty) + }); + match remove_semicolon { + Some((sp, StatementAsExpression::NeedsBoxing)) => { + err.multipart_suggestion( + "consider removing this semicolon and boxing the expressions", + vec![ + (first_span.shrink_to_lo(), "Box::new(".to_string()), + (first_span.shrink_to_hi(), ")".to_string()), + (second_span.shrink_to_lo(), "Box::new(".to_string()), + (second_span.shrink_to_hi(), ")".to_string()), + (sp, String::new()), + ], + Applicability::MachineApplicable, + ); + } + Some((sp, StatementAsExpression::CorrectType)) => { + err.span_suggestion_short( + sp, + "consider removing this semicolon", + "", + Applicability::MachineApplicable, + ); + } + None => { + for (id, ty) in [(first_id, second_ty), (second_id, first_ty)] { + if let Some(id) = id + && let hir::Node::Block(blk) = self.tcx.hir().get(id) + && self.consider_returning_binding(blk, ty, err) + { + break; + } + } + } + } + } + + pub(super) fn suggest_boxing_for_return_impl_trait( + &self, + err: &mut Diagnostic, + return_sp: Span, + arm_spans: impl Iterator<Item = Span>, + ) { + err.multipart_suggestion( + "you could change the return type to be a boxed trait object", + vec![ + (return_sp.with_hi(return_sp.lo() + BytePos(4)), "Box<dyn".to_string()), + (return_sp.shrink_to_hi(), ">".to_string()), + ], + Applicability::MaybeIncorrect, + ); + let sugg = arm_spans + .flat_map(|sp| { + [(sp.shrink_to_lo(), "Box::new(".to_string()), (sp.shrink_to_hi(), ")".to_string())] + .into_iter() + }) + .collect::<Vec<_>>(); + err.multipart_suggestion( + "if you change the return type to expect trait objects, box the returned expressions", + sugg, + Applicability::MaybeIncorrect, + ); + } + + pub(super) fn suggest_tuple_pattern( + &self, + cause: &ObligationCause<'tcx>, + exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, + diag: &mut Diagnostic, + ) { + // Heavily inspired by `FnCtxt::suggest_compatible_variants`, with + // some modifications due to that being in typeck and this being in infer. + if let ObligationCauseCode::Pattern { .. } = cause.code() { + if let ty::Adt(expected_adt, substs) = exp_found.expected.kind() { + let compatible_variants: Vec<_> = expected_adt + .variants() + .iter() + .filter(|variant| { + variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn) + }) + .filter_map(|variant| { + let sole_field = &variant.fields[0]; + let sole_field_ty = sole_field.ty(self.tcx, substs); + if self.same_type_modulo_infer(sole_field_ty, exp_found.found) { + let variant_path = + with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id)); + // FIXME #56861: DRYer prelude filtering + if let Some(path) = variant_path.strip_prefix("std::prelude::") { + if let Some((_, path)) = path.split_once("::") { + return Some(path.to_string()); + } + } + Some(variant_path) + } else { + None + } + }) + .collect(); + match &compatible_variants[..] { + [] => {} + [variant] => { + diag.multipart_suggestion_verbose( + &format!("try wrapping the pattern in `{}`", variant), + vec![ + (cause.span.shrink_to_lo(), format!("{}(", variant)), + (cause.span.shrink_to_hi(), ")".to_string()), + ], + Applicability::MaybeIncorrect, + ); + } + _ => { + // More than one matching variant. + diag.multipart_suggestions( + &format!( + "try wrapping the pattern in a variant of `{}`", + self.tcx.def_path_str(expected_adt.did()) + ), + compatible_variants.into_iter().map(|variant| { + vec![ + (cause.span.shrink_to_lo(), format!("{}(", variant)), + (cause.span.shrink_to_hi(), ")".to_string()), + ] + }), + Applicability::MaybeIncorrect, + ); + } + } + } + } + } + + /// A possible error is to forget to add `.await` when using futures: + /// + /// ```compile_fail,E0308 + /// async fn make_u32() -> u32 { + /// 22 + /// } + /// + /// fn take_u32(x: u32) {} + /// + /// async fn foo() { + /// let x = make_u32(); + /// take_u32(x); + /// } + /// ``` + /// + /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the + /// expected type. If this is the case, and we are inside of an async body, it suggests adding + /// `.await` to the tail of the expression. + pub(super) fn suggest_await_on_expect_found( + &self, + cause: &ObligationCause<'tcx>, + exp_span: Span, + exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, + diag: &mut Diagnostic, + ) { + debug!( + "suggest_await_on_expect_found: exp_span={:?}, expected_ty={:?}, found_ty={:?}", + exp_span, exp_found.expected, exp_found.found, + ); + + if let ObligationCauseCode::CompareImplItemObligation { .. } = cause.code() { + return; + } + + match ( + self.get_impl_future_output_ty(exp_found.expected), + self.get_impl_future_output_ty(exp_found.found), + ) { + (Some(exp), Some(found)) if self.same_type_modulo_infer(exp, found) => match cause + .code() + { + ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { + let then_span = self.find_block_span_from_hir_id(*then_id); + diag.multipart_suggestion( + "consider `await`ing on both `Future`s", + vec![ + (then_span.shrink_to_hi(), ".await".to_string()), + (exp_span.shrink_to_hi(), ".await".to_string()), + ], + Applicability::MaybeIncorrect, + ); + } + ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { + prior_arms, + .. + }) => { + if let [.., arm_span] = &prior_arms[..] { + diag.multipart_suggestion( + "consider `await`ing on both `Future`s", + vec![ + (arm_span.shrink_to_hi(), ".await".to_string()), + (exp_span.shrink_to_hi(), ".await".to_string()), + ], + Applicability::MaybeIncorrect, + ); + } else { + diag.help("consider `await`ing on both `Future`s"); + } + } + _ => { + diag.help("consider `await`ing on both `Future`s"); + } + }, + (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { + diag.span_suggestion_verbose( + exp_span.shrink_to_hi(), + "consider `await`ing on the `Future`", + ".await", + Applicability::MaybeIncorrect, + ); + } + (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() + { + ObligationCauseCode::Pattern { span: Some(then_span), .. } => { + diag.span_suggestion_verbose( + then_span.shrink_to_hi(), + "consider `await`ing on the `Future`", + ".await", + Applicability::MaybeIncorrect, + ); + } + ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { + let then_span = self.find_block_span_from_hir_id(*then_id); + diag.span_suggestion_verbose( + then_span.shrink_to_hi(), + "consider `await`ing on the `Future`", + ".await", + Applicability::MaybeIncorrect, + ); + } + ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { + ref prior_arms, + .. + }) => { + diag.multipart_suggestion_verbose( + "consider `await`ing on the `Future`", + prior_arms + .iter() + .map(|arm| (arm.shrink_to_hi(), ".await".to_string())) + .collect(), + Applicability::MaybeIncorrect, + ); + } + _ => {} + }, + _ => {} + } + } + + pub(super) fn suggest_accessing_field_where_appropriate( + &self, + cause: &ObligationCause<'tcx>, + exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, + diag: &mut Diagnostic, + ) { + debug!( + "suggest_accessing_field_where_appropriate(cause={:?}, exp_found={:?})", + cause, exp_found + ); + if let ty::Adt(expected_def, expected_substs) = exp_found.expected.kind() { + if expected_def.is_enum() { + return; + } + + if let Some((name, ty)) = expected_def + .non_enum_variant() + .fields + .iter() + .filter(|field| field.vis.is_accessible_from(field.did, self.tcx)) + .map(|field| (field.name, field.ty(self.tcx, expected_substs))) + .find(|(_, ty)| self.same_type_modulo_infer(*ty, exp_found.found)) + { + if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() { + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { + let suggestion = if expected_def.is_struct() { + format!("{}.{}", snippet, name) + } else if expected_def.is_union() { + format!("unsafe {{ {}.{} }}", snippet, name) + } else { + return; + }; + diag.span_suggestion( + span, + &format!( + "you might have meant to use field `{}` whose type is `{}`", + name, ty + ), + suggestion, + Applicability::MaybeIncorrect, + ); + } + } + } + } + } + + /// When encountering a case where `.as_ref()` on a `Result` or `Option` would be appropriate, + /// suggests it. + pub(super) fn suggest_as_ref_where_appropriate( + &self, + span: Span, + exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, + diag: &mut Diagnostic, + ) { + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) + && let Some(msg) = self.should_suggest_as_ref(exp_found.expected, exp_found.found) + { + diag.span_suggestion( + span, + msg, + // HACK: fix issue# 100605, suggesting convert from &Option<T> to Option<&T>, remove the extra `&` + format!("{}.as_ref()", snippet.trim_start_matches('&')), + Applicability::MachineApplicable, + ); + } + } + + pub fn should_suggest_as_ref(&self, expected: Ty<'tcx>, found: Ty<'tcx>) -> Option<&str> { + if let (ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) = + (expected.kind(), found.kind()) + { + if let ty::Adt(found_def, found_substs) = *found_ty.kind() { + if exp_def == &found_def { + let have_as_ref = &[ + ( + sym::Option, + "you can convert from `&Option<T>` to `Option<&T>` using \ + `.as_ref()`", + ), + ( + sym::Result, + "you can convert from `&Result<T, E>` to \ + `Result<&T, &E>` using `.as_ref()`", + ), + ]; + if let Some(msg) = have_as_ref.iter().find_map(|(name, msg)| { + self.tcx.is_diagnostic_item(*name, exp_def.did()).then_some(msg) + }) { + let mut show_suggestion = true; + for (exp_ty, found_ty) in + std::iter::zip(exp_substs.types(), found_substs.types()) + { + match *exp_ty.kind() { + ty::Ref(_, exp_ty, _) => { + match (exp_ty.kind(), found_ty.kind()) { + (_, ty::Param(_)) + | (_, ty::Infer(_)) + | (ty::Param(_), _) + | (ty::Infer(_), _) => {} + _ if self.same_type_modulo_infer(exp_ty, found_ty) => {} + _ => show_suggestion = false, + }; + } + ty::Param(_) | ty::Infer(_) => {} + _ => show_suggestion = false, + } + } + if show_suggestion { + return Some(*msg); + } + } + } + } + } + None + } + + /// Try to find code with pattern `if Some(..) = expr` + /// use a `visitor` to mark the `if` which its span contains given error span, + /// and then try to find a assignment in the `cond` part, which span is equal with error span + pub(super) fn suggest_let_for_letchains( + &self, + err: &mut Diagnostic, + cause: &ObligationCause<'_>, + span: Span, + ) { + let hir = self.tcx.hir(); + let fn_hir_id = hir.get_parent_node(cause.body_id); + if let Some(node) = self.tcx.hir().find(fn_hir_id) && + let hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn(_sig, _, body_id), .. + }) = node { + let body = hir.body(*body_id); + + /// Find the if expression with given span + struct IfVisitor { + pub result: bool, + pub found_if: bool, + pub err_span: Span, + } + + impl<'v> Visitor<'v> for IfVisitor { + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + if self.result { return; } + match ex.kind { + hir::ExprKind::If(cond, _, _) => { + self.found_if = true; + walk_expr(self, cond); + self.found_if = false; + } + _ => walk_expr(self, ex), + } + } + + fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) { + if let hir::StmtKind::Local(hir::Local { + span, pat: hir::Pat{..}, ty: None, init: Some(_), .. + }) = &ex.kind + && self.found_if + && span.eq(&self.err_span) { + self.result = true; + } + walk_stmt(self, ex); + } + + fn visit_body(&mut self, body: &'v hir::Body<'v>) { + hir::intravisit::walk_body(self, body); + } + } + + let mut visitor = IfVisitor { err_span: span, found_if: false, result: false }; + visitor.visit_body(&body); + if visitor.result { + err.subdiagnostic(SuggAddLetForLetChains{span: span.shrink_to_lo()}); + } + } + } +} + +impl<'tcx> TypeErrCtxt<'_, 'tcx> { + /// Be helpful when the user wrote `{... expr; }` and taking the `;` off + /// is enough to fix the error. + pub fn could_remove_semicolon( + &self, + blk: &'tcx hir::Block<'tcx>, + expected_ty: Ty<'tcx>, + ) -> Option<(Span, StatementAsExpression)> { + let blk = blk.innermost_block(); + // Do not suggest if we have a tail expr. + if blk.expr.is_some() { + return None; + } + let last_stmt = blk.stmts.last()?; + let hir::StmtKind::Semi(ref last_expr) = last_stmt.kind else { + return None; + }; + let last_expr_ty = self.typeck_results.as_ref()?.expr_ty_opt(*last_expr)?; + let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) { + _ if last_expr_ty.references_error() => return None, + _ if self.same_type_modulo_infer(last_expr_ty, expected_ty) => { + StatementAsExpression::CorrectType + } + (ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _)) + if last_def_id == exp_def_id => + { + StatementAsExpression::CorrectType + } + (ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => { + debug!( + "both opaque, likely future {:?} {:?} {:?} {:?}", + last_def_id, last_bounds, exp_def_id, exp_bounds + ); + + let last_local_id = last_def_id.as_local()?; + let exp_local_id = exp_def_id.as_local()?; + + match ( + &self.tcx.hir().expect_item(last_local_id).kind, + &self.tcx.hir().expect_item(exp_local_id).kind, + ) { + ( + hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }), + hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }), + ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| { + match (left, right) { + ( + hir::GenericBound::Trait(tl, ml), + hir::GenericBound::Trait(tr, mr), + ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() + && ml == mr => + { + true + } + ( + hir::GenericBound::LangItemTrait(langl, _, _, argsl), + hir::GenericBound::LangItemTrait(langr, _, _, argsr), + ) if langl == langr => { + // FIXME: consider the bounds! + debug!("{:?} {:?}", argsl, argsr); + true + } + _ => false, + } + }) => + { + StatementAsExpression::NeedsBoxing + } + _ => StatementAsExpression::CorrectType, + } + } + _ => return None, + }; + let span = if last_stmt.span.from_expansion() { + let mac_call = rustc_span::source_map::original_sp(last_stmt.span, blk.span); + self.tcx.sess.source_map().mac_call_stmt_semi_span(mac_call)? + } else { + last_stmt.span.with_lo(last_stmt.span.hi() - BytePos(1)) + }; + Some((span, needs_box)) + } + + /// Suggest returning a local binding with a compatible type if the block + /// has no return expression. + pub fn consider_returning_binding( + &self, + blk: &'tcx hir::Block<'tcx>, + expected_ty: Ty<'tcx>, + err: &mut Diagnostic, + ) -> bool { + let blk = blk.innermost_block(); + // Do not suggest if we have a tail expr. + if blk.expr.is_some() { + return false; + } + let mut shadowed = FxIndexSet::default(); + let mut candidate_idents = vec![]; + let mut find_compatible_candidates = |pat: &hir::Pat<'_>| { + if let hir::PatKind::Binding(_, hir_id, ident, _) = &pat.kind + && let Some(pat_ty) = self + .typeck_results + .as_ref() + .and_then(|typeck_results| typeck_results.node_type_opt(*hir_id)) + { + let pat_ty = self.resolve_vars_if_possible(pat_ty); + if self.same_type_modulo_infer(pat_ty, expected_ty) + && !(pat_ty, expected_ty).references_error() + && shadowed.insert(ident.name) + { + candidate_idents.push((*ident, pat_ty)); + } + } + true + }; + + let hir = self.tcx.hir(); + for stmt in blk.stmts.iter().rev() { + let hir::StmtKind::Local(local) = &stmt.kind else { continue; }; + local.pat.walk(&mut find_compatible_candidates); + } + match hir.find(hir.get_parent_node(blk.hir_id)) { + Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => { + match hir.find(hir.get_parent_node(*hir_id)) { + Some(hir::Node::Arm(hir::Arm { pat, .. })) => { + pat.walk(&mut find_compatible_candidates); + } + Some( + hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(_, body), + .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)), + .. + }) + | hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(hir::Closure { body, .. }), + .. + }), + ) => { + for param in hir.body(*body).params { + param.pat.walk(&mut find_compatible_candidates); + } + } + Some(hir::Node::Expr(hir::Expr { + kind: + hir::ExprKind::If( + hir::Expr { kind: hir::ExprKind::Let(let_), .. }, + then_block, + _, + ), + .. + })) if then_block.hir_id == *hir_id => { + let_.pat.walk(&mut find_compatible_candidates); + } + _ => {} + } + } + _ => {} + } + + match &candidate_idents[..] { + [(ident, _ty)] => { + let sm = self.tcx.sess.source_map(); + if let Some(stmt) = blk.stmts.last() { + let stmt_span = sm.stmt_span(stmt.span, blk.span); + let sugg = if sm.is_multiline(blk.span) + && let Some(spacing) = sm.indentation_before(stmt_span) + { + format!("\n{spacing}{ident}") + } else { + format!(" {ident}") + }; + err.span_suggestion_verbose( + stmt_span.shrink_to_hi(), + format!("consider returning the local binding `{ident}`"), + sugg, + Applicability::MaybeIncorrect, + ); + } else { + let sugg = if sm.is_multiline(blk.span) + && let Some(spacing) = sm.indentation_before(blk.span.shrink_to_lo()) + { + format!("\n{spacing} {ident}\n{spacing}") + } else { + format!(" {ident} ") + }; + let left_span = sm.span_through_char(blk.span, '{').shrink_to_hi(); + err.span_suggestion_verbose( + sm.span_extend_while(left_span, |c| c.is_whitespace()).unwrap_or(left_span), + format!("consider returning the local binding `{ident}`"), + sugg, + Applicability::MaybeIncorrect, + ); + } + true + } + values if (1..3).contains(&values.len()) => { + let spans = values.iter().map(|(ident, _)| ident.span).collect::<Vec<_>>(); + err.span_note(spans, "consider returning one of these bindings"); + true + } + _ => false, + } + } +} diff --git a/compiler/rustc_infer/src/infer/note.rs b/compiler/rustc_infer/src/infer/note.rs new file mode 100644 index 00000000000..2ccbd164faa --- /dev/null +++ b/compiler/rustc_infer/src/infer/note.rs @@ -0,0 +1,203 @@ +impl<'tcx> TypeErrCtxt<'_, 'tcx> { + fn note_error_origin( + &self, + err: &mut Diagnostic, + cause: &ObligationCause<'tcx>, + exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>, + terr: TypeError<'tcx>, + ) { + match *cause.code() { + ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => { + let ty = self.resolve_vars_if_possible(root_ty); + if !matches!(ty.kind(), ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_))) + { + // don't show type `_` + if span.desugaring_kind() == Some(DesugaringKind::ForLoop) + && let ty::Adt(def, substs) = ty.kind() + && Some(def.did()) == self.tcx.get_diagnostic_item(sym::Option) + { + err.span_label(span, format!("this is an iterator with items of type `{}`", substs.type_at(0))); + } else { + err.span_label(span, format!("this expression has type `{}`", ty)); + } + } + if let Some(ty::error::ExpectedFound { found, .. }) = exp_found + && ty.is_box() && ty.boxed_ty() == found + && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) + { + err.span_suggestion( + span, + "consider dereferencing the boxed value", + format!("*{}", snippet), + Applicability::MachineApplicable, + ); + } + } + ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => { + err.span_label(span, "expected due to this"); + } + ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { + arm_block_id, + arm_span, + arm_ty, + prior_arm_block_id, + prior_arm_span, + prior_arm_ty, + source, + ref prior_arms, + scrut_hir_id, + opt_suggest_box_span, + scrut_span, + .. + }) => match source { + hir::MatchSource::TryDesugar => { + if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { + 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.as_ref().and_then(|typeck_results| { + typeck_results.expr_ty_opt(arg_expr) + }) + } else { + bug!("try desugaring w/out call expr as scrutinee"); + }; + + match scrut_ty { + Some(ty) if expected == ty => { + let source_map = self.tcx.sess.source_map(); + err.span_suggestion( + source_map.end_point(cause.span), + "try removing this `?`", + "", + Applicability::MachineApplicable, + ); + } + _ => {} + } + } + } + _ => { + // `prior_arm_ty` can be `!`, `expected` will have better info when present. + let t = self.resolve_vars_if_possible(match exp_found { + Some(ty::error::ExpectedFound { expected, .. }) => expected, + _ => prior_arm_ty, + }); + let source_map = self.tcx.sess.source_map(); + let mut any_multiline_arm = source_map.is_multiline(arm_span); + if prior_arms.len() <= 4 { + for sp in prior_arms { + any_multiline_arm |= source_map.is_multiline(*sp); + err.span_label(*sp, format!("this is found to be of type `{}`", t)); + } + } else if let Some(sp) = prior_arms.last() { + any_multiline_arm |= source_map.is_multiline(*sp); + err.span_label( + *sp, + format!("this and all prior arms are found to be of type `{}`", t), + ); + } + let outer_error_span = if any_multiline_arm { + // Cover just `match` and the scrutinee expression, not + // the entire match body, to reduce diagram noise. + cause.span.shrink_to_lo().to(scrut_span) + } else { + cause.span + }; + let msg = "`match` arms have incompatible types"; + err.span_label(outer_error_span, msg); + self.suggest_remove_semi_or_return_binding( + err, + prior_arm_block_id, + prior_arm_ty, + prior_arm_span, + arm_block_id, + arm_ty, + arm_span, + ); + if let Some(ret_sp) = opt_suggest_box_span { + // Get return type span and point to it. + self.suggest_boxing_for_return_impl_trait( + err, + ret_sp, + prior_arms.iter().chain(std::iter::once(&arm_span)).map(|s| *s), + ); + } + } + }, + ObligationCauseCode::IfExpression(box IfExpressionCause { + then_id, + else_id, + then_ty, + else_ty, + outer_span, + opt_suggest_box_span, + }) => { + let then_span = self.find_block_span_from_hir_id(then_id); + let else_span = self.find_block_span_from_hir_id(else_id); + err.span_label(then_span, "expected because of this"); + if let Some(sp) = outer_span { + err.span_label(sp, "`if` and `else` have incompatible types"); + } + self.suggest_remove_semi_or_return_binding( + err, + Some(then_id), + then_ty, + then_span, + Some(else_id), + else_ty, + else_span, + ); + if let Some(ret_sp) = opt_suggest_box_span { + self.suggest_boxing_for_return_impl_trait( + err, + ret_sp, + [then_span, else_span].into_iter(), + ); + } + } + ObligationCauseCode::LetElse => { + err.help("try adding a diverging expression, such as `return` or `panic!(..)`"); + err.help("...or use `match` instead of `let...else`"); + } + _ => { + if let ObligationCauseCode::BindingObligation(_, span) + | ObligationCauseCode::ExprBindingObligation(_, span, ..) + = cause.code().peel_derives() + && let TypeError::RegionsPlaceholderMismatch = terr + { + err.span_note( * span, + "the lifetime requirement is introduced here"); + } + } + } + } +} + +impl<'tcx> InferCtxt<'tcx> { + /// Given a [`hir::Block`], get the span of its last expression or + /// statement, peeling off any inner blocks. + pub fn find_block_span(&self, block: &'tcx hir::Block<'tcx>) -> Span { + let block = block.innermost_block(); + if let Some(expr) = &block.expr { + expr.span + } else if let Some(stmt) = block.stmts.last() { + // possibly incorrect trailing `;` in the else arm + stmt.span + } else { + // empty block; point at its entirety + block.span + } + } + + /// Given a [`hir::HirId`] for a block, get the span of its last expression + /// or statement, peeling off any inner blocks. + pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span { + match self.tcx.hir().get(hir_id) { + hir::Node::Block(blk) => self.find_block_span(blk), + // The parser was in a weird state if either of these happen, but + // it's better not to panic. + hir::Node::Expr(e) => e.span, + _ => rustc_span::DUMMY_SP, + } + } +} diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index f75c8669fa1..89d9450cf4e 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -158,7 +158,7 @@ pub fn create_resolver( sess: Lrc<Session>, metadata_loader: Box<MetadataLoaderDyn>, krate: &ast::Crate, - crate_name: &str, + crate_name: Symbol, ) -> BoxedResolver { trace!("create_resolver"); BoxedResolver::new(sess, move |sess, resolver_arenas| { @@ -171,7 +171,7 @@ pub fn register_plugins<'a>( metadata_loader: &'a dyn MetadataLoader, register_lints: impl Fn(&Session, &mut LintStore), mut krate: ast::Crate, - crate_name: &str, + crate_name: Symbol, ) -> Result<(ast::Crate, LintStore)> { krate = sess.time("attributes_injection", || { rustc_builtin_macros::cmdline_attrs::inject( @@ -228,19 +228,21 @@ fn pre_expansion_lint<'a>( lint_store: &LintStore, registered_tools: &RegisteredTools, check_node: impl EarlyCheckNode<'a>, - node_name: &str, + node_name: Symbol, ) { - sess.prof.generic_activity_with_arg("pre_AST_expansion_lint_checks", node_name).run(|| { - rustc_lint::check_ast_node( - sess, - true, - lint_store, - registered_tools, - None, - rustc_lint::BuiltinCombinedPreExpansionLintPass::new(), - check_node, - ); - }); + sess.prof.generic_activity_with_arg("pre_AST_expansion_lint_checks", node_name.as_str()).run( + || { + rustc_lint::check_ast_node( + sess, + true, + lint_store, + registered_tools, + None, + rustc_lint::BuiltinCombinedPreExpansionLintPass::new(), + check_node, + ); + }, + ); } // Cannot implement directly for `LintStore` due to trait coherence. @@ -254,7 +256,7 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> { node_id: ast::NodeId, attrs: &[ast::Attribute], items: &[rustc_ast::ptr::P<ast::Item>], - name: &str, + name: Symbol, ) { pre_expansion_lint(sess, self.0, registered_tools, (node_id, attrs, items), name); } @@ -268,7 +270,7 @@ pub fn configure_and_expand( sess: &Session, lint_store: &LintStore, mut krate: ast::Crate, - crate_name: &str, + crate_name: Symbol, resolver: &mut Resolver<'_>, ) -> Result<ast::Crate> { trace!("configure_and_expand"); @@ -462,7 +464,7 @@ fn generated_output_paths( sess: &Session, outputs: &OutputFilenames, exact_name: bool, - crate_name: &str, + crate_name: Symbol, ) -> Vec<PathBuf> { let mut out_filenames = Vec::new(); for output_type in sess.opts.output_types.keys() { @@ -661,7 +663,7 @@ pub fn prepare_outputs( compiler: &Compiler, krate: &ast::Crate, boxed_resolver: &RefCell<BoxedResolver>, - crate_name: &str, + crate_name: Symbol, ) -> Result<OutputFilenames> { let _timer = sess.timer("prepare_outputs"); @@ -771,7 +773,7 @@ pub fn create_global_ctxt<'tcx>( dep_graph: DepGraph, resolver: Rc<RefCell<BoxedResolver>>, outputs: OutputFilenames, - crate_name: &str, + crate_name: Symbol, queries: &'tcx OnceCell<TcxQueries<'tcx>>, global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>, arena: &'tcx WorkerLocal<Arena<'tcx>>, @@ -803,9 +805,9 @@ pub fn create_global_ctxt<'tcx>( }); let ty::ResolverOutputs { - definitions, global_ctxt: untracked_resolutions, ast_lowering: untracked_resolver_for_lowering, + untracked, } = resolver_outputs; let gcx = sess.time("setup_global_ctxt", || { @@ -815,8 +817,8 @@ pub fn create_global_ctxt<'tcx>( lint_store, arena, hir_arena, - definitions, untracked_resolutions, + untracked, krate, dep_graph, queries.on_disk_cache.as_ref().map(OnDiskCache::as_dyn), diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index f5ddd647b24..39e1f2204b0 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -17,6 +17,7 @@ use rustc_query_impl::Queries as TcxQueries; use rustc_session::config::{self, OutputFilenames, OutputType}; use rustc_session::{output::find_crate_name, Session}; use rustc_span::symbol::sym; +use rustc_span::Symbol; use std::any::Any; use std::cell::{Ref, RefCell, RefMut}; use std::rc::Rc; @@ -74,7 +75,7 @@ pub struct Queries<'tcx> { dep_graph_future: Query<Option<DepGraphFuture>>, parse: Query<ast::Crate>, - crate_name: Query<String>, + crate_name: Query<Symbol>, register_plugins: Query<(ast::Crate, Lrc<LintStore>)>, expansion: Query<(Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>, dep_graph: Query<DepGraph>, @@ -135,7 +136,7 @@ impl<'tcx> Queries<'tcx> { &*self.codegen_backend().metadata_loader(), self.compiler.register_lints.as_deref().unwrap_or_else(|| empty), krate, - &crate_name, + crate_name, )?; // Compute the dependency graph (in the background). We want to do @@ -149,7 +150,7 @@ impl<'tcx> Queries<'tcx> { }) } - pub fn crate_name(&self) -> Result<&Query<String>> { + pub fn crate_name(&self) -> Result<&Query<Symbol>> { self.crate_name.compute(|| { Ok({ let parse_result = self.parse()?; @@ -165,7 +166,7 @@ impl<'tcx> Queries<'tcx> { ) -> Result<&Query<(Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>> { trace!("expansion"); self.expansion.compute(|| { - let crate_name = self.crate_name()?.peek().clone(); + let crate_name = *self.crate_name()?.peek(); let (krate, lint_store) = self.register_plugins()?.take(); let _timer = self.session().timer("configure_and_expand"); let sess = self.session(); @@ -173,10 +174,10 @@ impl<'tcx> Queries<'tcx> { sess.clone(), self.codegen_backend().metadata_loader(), &krate, - &crate_name, + crate_name, ); let krate = resolver.access(|resolver| { - passes::configure_and_expand(sess, &lint_store, krate, &crate_name, resolver) + passes::configure_and_expand(sess, &lint_store, krate, crate_name, resolver) })?; Ok((Lrc::new(krate), Rc::new(RefCell::new(resolver)), lint_store)) }) @@ -201,20 +202,20 @@ impl<'tcx> Queries<'tcx> { pub fn prepare_outputs(&self) -> Result<&Query<OutputFilenames>> { self.prepare_outputs.compute(|| { let (krate, boxed_resolver, _) = &*self.expansion()?.peek(); - let crate_name = self.crate_name()?.peek(); + let crate_name = *self.crate_name()?.peek(); passes::prepare_outputs( self.session(), self.compiler, krate, &*boxed_resolver, - &crate_name, + crate_name, ) }) } pub fn global_ctxt(&'tcx self) -> Result<&Query<QueryContext<'tcx>>> { self.global_ctxt.compute(|| { - let crate_name = self.crate_name()?.peek().clone(); + let crate_name = *self.crate_name()?.peek(); let outputs = self.prepare_outputs()?.take(); let dep_graph = self.dep_graph()?.peek().clone(); let (krate, resolver, lint_store) = self.expansion()?.take(); @@ -225,7 +226,7 @@ impl<'tcx> Queries<'tcx> { dep_graph, resolver, outputs, - &crate_name, + crate_name, &self.queries, &self.gcx, &self.arena, diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index d0d34d8d2b4..0932eee9237 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -53,7 +53,8 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, InnerSpan, Span}; use rustc_target::abi::{Abi, VariantIdx}; -use rustc_trait_selection::traits::{self, misc::can_type_implement_copy}; +use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt}; +use rustc_trait_selection::traits::{self, misc::can_type_implement_copy, EvaluationResult}; use crate::nonstandard_style::{method_context, MethodLateContext}; @@ -96,6 +97,7 @@ fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr { } impl EarlyLintPass for WhileTrue { + #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { if let ast::ExprKind::While(cond, _, label) = &e.kind && let cond = pierce_parens(cond) @@ -360,6 +362,7 @@ impl EarlyLintPass for UnsafeCode { } } + #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { if let ast::ExprKind::Block(ref blk, _) = e.kind { // Don't warn about generated blocks; that'll just pollute the output. @@ -582,6 +585,7 @@ impl MissingDoc { } impl<'tcx> LateLintPass<'tcx> for MissingDoc { + #[inline] fn enter_lint_attrs(&mut self, _cx: &LateContext<'_>, attrs: &[ast::Attribute]) { let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| { @@ -750,10 +754,39 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { if def.has_dtor(cx.tcx) { return; } + + // If the type contains a raw pointer, it may represent something like a handle, + // and recommending Copy might be a bad idea. + for field in def.all_fields() { + let did = field.did; + if cx.tcx.type_of(did).is_unsafe_ptr() { + return; + } + } let param_env = ty::ParamEnv::empty(); if ty.is_copy_modulo_regions(cx.tcx, param_env) { return; } + + // We shouldn't recommend implementing `Copy` on stateful things, + // such as iterators. + if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator) { + if cx.tcx.infer_ctxt().build().type_implements_trait(iter_trait, [ty], param_env) + == EvaluationResult::EvaluatedToOk + { + return; + } + } + + // Default value of clippy::trivially_copy_pass_by_ref + const MAX_SIZE: u64 = 256; + + if let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes()) { + if size > MAX_SIZE { + return; + } + } + if can_type_implement_copy( cx.tcx, param_env, diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 52363b0be2d..5d81370c35a 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -37,7 +37,9 @@ pub struct EarlyContextAndPasses<'a> { } impl<'a> EarlyContextAndPasses<'a> { - fn check_id(&mut self, id: ast::NodeId) { + // This always-inlined function is for the hot call site. + #[inline(always)] + fn inlined_check_id(&mut self, id: ast::NodeId) { for early_lint in self.context.buffered.take(id) { let BufferedEarlyLint { span, msg, node_id: _, lint_id, diagnostic } = early_lint; self.context.lookup_with_diagnostics( @@ -50,6 +52,11 @@ impl<'a> EarlyContextAndPasses<'a> { } } + // This non-inlined function is for the cold call sites. + fn check_id(&mut self, id: ast::NodeId) { + self.inlined_check_id(id) + } + /// Merge the lints specified by any lint attributes into the /// current lint context, call the provided function, then reset the /// lints in effect to their previous state. @@ -61,7 +68,7 @@ impl<'a> EarlyContextAndPasses<'a> { debug!(?id); let push = self.context.builder.push(attrs, is_crate_node, None); - self.check_id(id); + self.inlined_check_id(id); debug!("early context: enter_attrs({:?})", attrs); run_early_passes!(self, enter_lint_attrs, attrs); f(self); diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs index 7106e75dba2..dc2f5c0e296 100644 --- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs +++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs @@ -121,6 +121,7 @@ impl EarlyLintPass for HiddenUnicodeCodepoints { } } + #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { // byte strings are already handled well enough by `EscapeError::NonAsciiCharInByteString` match &expr.kind { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 10bae36e0fd..1990a74841b 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -127,6 +127,7 @@ fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { late::late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new()); } +// See the comment on `BuiltinCombinedEarlyLintPass`, which is similar. early_lint_methods!( declare_combined_early_lint_pass, [ @@ -137,6 +138,9 @@ early_lint_methods!( ] ); +// Declare `BuiltinCombinedEarlyLintPass`, a lint pass that combines multiple +// lint passes into a single pass for maximum speed. Each `check_foo` method +// within this pass simply calls `check_foo` once per listed lint. early_lint_methods!( declare_combined_early_lint_pass, [ @@ -162,7 +166,9 @@ early_lint_methods!( ] ); -// FIXME: Make a separate lint type which do not require typeck tables +// FIXME: Make a separate lint type which does not require typeck tables. + +// See the comment on `BuiltinCombinedEarlyLintPass`, which is similar. late_lint_methods!( declare_combined_late_lint_pass, [ @@ -179,10 +185,10 @@ late_lint_methods!( // Keeps a global list of foreign declarations. ClashingExternDeclarations: ClashingExternDeclarations::new(), ] - ], - ['tcx] + ] ); +// See the comment on `BuiltinCombinedEarlyLintPass`, which is similar. late_lint_methods!( declare_combined_late_lint_pass, [ @@ -229,8 +235,7 @@ late_lint_methods!( NamedAsmLabels: NamedAsmLabels, OpaqueHiddenInferredBound: OpaqueHiddenInferredBound, ] - ], - ['tcx] + ] ); pub fn new_lint_store(internal_lints: bool) -> LintStore { diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 2f53986139e..00922cef384 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -9,49 +9,49 @@ use rustc_span::Span; #[macro_export] macro_rules! late_lint_methods { - ($macro:path, $args:tt, [$hir:tt]) => ( - $macro!($args, [$hir], [ - fn check_body(a: &$hir hir::Body<$hir>); - fn check_body_post(a: &$hir hir::Body<$hir>); + ($macro:path, $args:tt) => ( + $macro!($args, [ + fn check_body(a: &'tcx hir::Body<'tcx>); + fn check_body_post(a: &'tcx hir::Body<'tcx>); fn check_crate(); fn check_crate_post(); - fn check_mod(a: &$hir hir::Mod<$hir>, b: hir::HirId); - fn check_foreign_item(a: &$hir hir::ForeignItem<$hir>); - fn check_item(a: &$hir hir::Item<$hir>); - fn check_item_post(a: &$hir hir::Item<$hir>); - fn check_local(a: &$hir hir::Local<$hir>); - fn check_block(a: &$hir hir::Block<$hir>); - fn check_block_post(a: &$hir hir::Block<$hir>); - fn check_stmt(a: &$hir hir::Stmt<$hir>); - fn check_arm(a: &$hir hir::Arm<$hir>); - fn check_pat(a: &$hir hir::Pat<$hir>); - fn check_expr(a: &$hir hir::Expr<$hir>); - fn check_expr_post(a: &$hir hir::Expr<$hir>); - fn check_ty(a: &$hir hir::Ty<$hir>); - fn check_generic_param(a: &$hir hir::GenericParam<$hir>); - fn check_generics(a: &$hir hir::Generics<$hir>); - fn check_poly_trait_ref(a: &$hir hir::PolyTraitRef<$hir>); + fn check_mod(a: &'tcx hir::Mod<'tcx>, b: hir::HirId); + fn check_foreign_item(a: &'tcx hir::ForeignItem<'tcx>); + fn check_item(a: &'tcx hir::Item<'tcx>); + fn check_item_post(a: &'tcx hir::Item<'tcx>); + fn check_local(a: &'tcx hir::Local<'tcx>); + fn check_block(a: &'tcx hir::Block<'tcx>); + fn check_block_post(a: &'tcx hir::Block<'tcx>); + fn check_stmt(a: &'tcx hir::Stmt<'tcx>); + fn check_arm(a: &'tcx hir::Arm<'tcx>); + fn check_pat(a: &'tcx hir::Pat<'tcx>); + fn check_expr(a: &'tcx hir::Expr<'tcx>); + fn check_expr_post(a: &'tcx hir::Expr<'tcx>); + fn check_ty(a: &'tcx hir::Ty<'tcx>); + fn check_generic_param(a: &'tcx hir::GenericParam<'tcx>); + fn check_generics(a: &'tcx hir::Generics<'tcx>); + fn check_poly_trait_ref(a: &'tcx hir::PolyTraitRef<'tcx>); fn check_fn( - a: rustc_hir::intravisit::FnKind<$hir>, - b: &$hir hir::FnDecl<$hir>, - c: &$hir hir::Body<$hir>, + a: rustc_hir::intravisit::FnKind<'tcx>, + b: &'tcx hir::FnDecl<'tcx>, + c: &'tcx hir::Body<'tcx>, d: Span, e: hir::HirId); - fn check_trait_item(a: &$hir hir::TraitItem<$hir>); - fn check_impl_item(a: &$hir hir::ImplItem<$hir>); - fn check_impl_item_post(a: &$hir hir::ImplItem<$hir>); - fn check_struct_def(a: &$hir hir::VariantData<$hir>); - fn check_field_def(a: &$hir hir::FieldDef<$hir>); - fn check_variant(a: &$hir hir::Variant<$hir>); - fn check_path(a: &hir::Path<$hir>, b: hir::HirId); - fn check_attribute(a: &$hir ast::Attribute); + fn check_trait_item(a: &'tcx hir::TraitItem<'tcx>); + fn check_impl_item(a: &'tcx hir::ImplItem<'tcx>); + fn check_impl_item_post(a: &'tcx hir::ImplItem<'tcx>); + fn check_struct_def(a: &'tcx hir::VariantData<'tcx>); + fn check_field_def(a: &'tcx hir::FieldDef<'tcx>); + fn check_variant(a: &'tcx hir::Variant<'tcx>); + fn check_path(a: &hir::Path<'tcx>, b: hir::HirId); + fn check_attribute(a: &'tcx ast::Attribute); /// Called when entering a syntax node that can have lint attributes such /// as `#[allow(...)]`. Called with *all* the attributes of that node. - fn enter_lint_attrs(a: &$hir [ast::Attribute]); + fn enter_lint_attrs(a: &'tcx [ast::Attribute]); /// Counterpart to `enter_lint_attrs`. - fn exit_lint_attrs(a: &$hir [ast::Attribute]); + fn exit_lint_attrs(a: &'tcx [ast::Attribute]); ]); ) } @@ -66,21 +66,23 @@ macro_rules! late_lint_methods { // contains a few lint-specific methods with no equivalent in `Visitor`. macro_rules! declare_late_lint_pass { - ([], [$hir:tt], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( - pub trait LateLintPass<$hir>: LintPass { - $(#[inline(always)] fn $name(&mut self, _: &LateContext<$hir>, $(_: $arg),*) {})* + ([], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( + pub trait LateLintPass<'tcx>: LintPass { + $(#[inline(always)] fn $name(&mut self, _: &LateContext<'tcx>, $(_: $arg),*) {})* } ) } -late_lint_methods!(declare_late_lint_pass, [], ['tcx]); +// Declare the `LateLintPass` trait, which contains empty default definitions +// for all the `check_*` methods. +late_lint_methods!(declare_late_lint_pass, []); impl LateLintPass<'_> for HardwiredLints {} #[macro_export] macro_rules! expand_combined_late_lint_pass_method { - ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ - $($self.$passes.$name $params;)* + ([$($pass:ident),*], $self: ident, $name: ident, $params:tt) => ({ + $($self.$pass.$name $params;)* }) } @@ -95,28 +97,28 @@ macro_rules! expand_combined_late_lint_pass_methods { #[macro_export] macro_rules! declare_combined_late_lint_pass { - ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], [$hir:tt], $methods:tt) => ( + ([$v:vis $name:ident, [$($pass:ident: $constructor:expr,)*]], $methods:tt) => ( #[allow(non_snake_case)] $v struct $name { - $($passes: $passes,)* + $($pass: $pass,)* } impl $name { $v fn new() -> Self { Self { - $($passes: $constructor,)* + $($pass: $constructor,)* } } $v fn get_lints() -> LintArray { let mut lints = Vec::new(); - $(lints.extend_from_slice(&$passes::get_lints());)* + $(lints.extend_from_slice(&$pass::get_lints());)* lints } } impl<'tcx> LateLintPass<'tcx> for $name { - expand_combined_late_lint_pass_methods!([$($passes),*], $methods); + expand_combined_late_lint_pass_methods!([$($pass),*], $methods); } #[allow(rustc::lint_pass_impl_without_macro)] @@ -176,12 +178,14 @@ macro_rules! declare_early_lint_pass { ) } +// Declare the `EarlyLintPass` trait, which contains empty default definitions +// for all the `check_*` methods. early_lint_methods!(declare_early_lint_pass, []); #[macro_export] macro_rules! expand_combined_early_lint_pass_method { - ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ - $($self.$passes.$name $params;)* + ([$($pass:ident),*], $self: ident, $name: ident, $params:tt) => ({ + $($self.$pass.$name $params;)* }) } @@ -196,28 +200,28 @@ macro_rules! expand_combined_early_lint_pass_methods { #[macro_export] macro_rules! declare_combined_early_lint_pass { - ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], $methods:tt) => ( + ([$v:vis $name:ident, [$($pass:ident: $constructor:expr,)*]], $methods:tt) => ( #[allow(non_snake_case)] $v struct $name { - $($passes: $passes,)* + $($pass: $pass,)* } impl $name { $v fn new() -> Self { Self { - $($passes: $constructor,)* + $($pass: $constructor,)* } } $v fn get_lints() -> LintArray { let mut lints = Vec::new(); - $(lints.extend_from_slice(&$passes::get_lints());)* + $(lints.extend_from_slice(&$pass::get_lints());)* lints } } impl EarlyLintPass for $name { - expand_combined_early_lint_pass_methods!([$($passes),*], $methods); + expand_combined_early_lint_pass_methods!([$($pass),*], $methods); } #[allow(rustc::lint_pass_impl_without_macro)] diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index b5db94f8c06..dc352778f1d 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -617,7 +617,10 @@ trait UnusedDelimLint { lhs_needs_parens || (followed_by_block && match &inner.kind { - ExprKind::Ret(_) | ExprKind::Break(..) | ExprKind::Yield(..) => true, + ExprKind::Ret(_) + | ExprKind::Break(..) + | ExprKind::Yield(..) + | ExprKind::Yeet(..) => true, ExprKind::Range(_lhs, Some(rhs), _limits) => { matches!(rhs.kind, ExprKind::Block(..)) } @@ -946,6 +949,7 @@ impl UnusedParens { } impl EarlyLintPass for UnusedParens { + #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { match e.kind { ExprKind::Let(ref pat, _, _) | ExprKind::ForLoop(ref pat, ..) => { @@ -1164,6 +1168,7 @@ impl EarlyLintPass for UnusedBraces { <Self as UnusedDelimLint>::check_stmt(self, cx, s) } + #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { <Self as UnusedDelimLint>::check_expr(self, cx, e); diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 79f06ac146c..0b3c057345a 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -238,18 +238,20 @@ fn main() { if !is_crossed { cmd.arg("--system-libs"); - } else if target.contains("windows-gnu") { - println!("cargo:rustc-link-lib=shell32"); - println!("cargo:rustc-link-lib=uuid"); - } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") { - println!("cargo:rustc-link-lib=z"); - } else if target.starts_with("arm") + } + + if (target.starts_with("arm") && !target.contains("freebsd")) || target.starts_with("mips-") || target.starts_with("mipsel-") || target.starts_with("powerpc-") { // 32-bit targets need to link libatomic. println!("cargo:rustc-link-lib=atomic"); + } else if target.contains("windows-gnu") { + println!("cargo:rustc-link-lib=shell32"); + println!("cargo:rustc-link-lib=uuid"); + } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") { + println!("cargo:rustc-link-lib=z"); } cmd.args(&components); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 3a748f38995..5831d4693f1 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1476,13 +1476,13 @@ extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) { extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, - OperandBundleDef *Bundle) { + OperandBundleDef **OpBundles, + unsigned NumOpBundles) { Value *Callee = unwrap(Fn); FunctionType *FTy = unwrap<FunctionType>(Ty); - unsigned Len = Bundle ? 1 : 0; - ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len); return wrap(unwrap(B)->CreateCall( - FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles)); + FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), + makeArrayRef(*OpBundles, NumOpBundles))); } extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) { @@ -1522,14 +1522,14 @@ extern "C" LLVMValueRef LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, - OperandBundleDef *Bundle, const char *Name) { + OperandBundleDef **OpBundles, unsigned NumOpBundles, + const char *Name) { Value *Callee = unwrap(Fn); FunctionType *FTy = unwrap<FunctionType>(Ty); - unsigned Len = Bundle ? 1 : 0; - ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len); return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch), makeArrayRef(unwrap(Args), NumArgs), - Bundles, Name)); + makeArrayRef(*OpBundles, NumOpBundles), + Name)); } extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B, diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 1a2389c7a84..01d7f3e03c5 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -13,7 +13,7 @@ use rustc_ast::expand::allocator::AllocatorKind; use rustc_ast::{self as ast, *}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, ReadGuard}; use rustc_expand::base::SyntaxExtension; use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; @@ -68,11 +68,12 @@ impl std::fmt::Debug for CStore { pub struct CrateLoader<'a> { // Immutable configuration. sess: &'a Session, - metadata_loader: Box<MetadataLoaderDyn>, + metadata_loader: &'a MetadataLoaderDyn, + definitions: ReadGuard<'a, Definitions>, local_crate_name: Symbol, // Mutable output. - cstore: CStore, - used_extern_options: FxHashSet<Symbol>, + cstore: &'a mut CStore, + used_extern_options: &'a mut FxHashSet<Symbol>, } pub enum LoadedMacro { @@ -239,47 +240,49 @@ impl CStore { ); } } + + pub fn new(sess: &Session) -> CStore { + let mut stable_crate_ids = FxHashMap::default(); + stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE); + CStore { + // We add an empty entry for LOCAL_CRATE (which maps to zero) in + // order to make array indices in `metas` match with the + // corresponding `CrateNum`. This first entry will always remain + // `None`. + metas: IndexVec::from_elem_n(None, 1), + injected_panic_runtime: None, + allocator_kind: None, + alloc_error_handler_kind: None, + has_global_allocator: false, + has_alloc_error_handler: false, + stable_crate_ids, + unused_externs: Vec::new(), + } + } } impl<'a> CrateLoader<'a> { pub fn new( sess: &'a Session, - metadata_loader: Box<MetadataLoaderDyn>, - local_crate_name: &str, + metadata_loader: &'a MetadataLoaderDyn, + local_crate_name: Symbol, + cstore: &'a mut CStore, + definitions: ReadGuard<'a, Definitions>, + used_extern_options: &'a mut FxHashSet<Symbol>, ) -> Self { - let mut stable_crate_ids = FxHashMap::default(); - stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE); - CrateLoader { sess, metadata_loader, - local_crate_name: Symbol::intern(local_crate_name), - cstore: CStore { - // We add an empty entry for LOCAL_CRATE (which maps to zero) in - // order to make array indices in `metas` match with the - // corresponding `CrateNum`. This first entry will always remain - // `None`. - metas: IndexVec::from_elem_n(None, 1), - injected_panic_runtime: None, - allocator_kind: None, - alloc_error_handler_kind: None, - has_global_allocator: false, - has_alloc_error_handler: false, - stable_crate_ids, - unused_externs: Vec::new(), - }, - used_extern_options: Default::default(), + local_crate_name, + cstore, + used_extern_options, + definitions, } } - pub fn cstore(&self) -> &CStore { &self.cstore } - pub fn into_cstore(self) -> CStore { - self.cstore - } - fn existing_match(&self, name: Symbol, hash: Option<Svh>, kind: PathKind) -> Option<CrateNum> { for (cnum, data) in self.cstore.iter_crate_data() { if data.name() != name { @@ -989,7 +992,6 @@ impl<'a> CrateLoader<'a> { pub fn process_extern_crate( &mut self, item: &ast::Item, - definitions: &Definitions, def_id: LocalDefId, ) -> Option<CrateNum> { match item.kind { @@ -1000,7 +1002,7 @@ impl<'a> CrateLoader<'a> { ); let name = match orig_name { Some(orig_name) => { - validate_crate_name(self.sess, orig_name.as_str(), Some(item.span)); + validate_crate_name(self.sess, orig_name, Some(item.span)); orig_name } None => item.ident.name, @@ -1013,7 +1015,7 @@ impl<'a> CrateLoader<'a> { let cnum = self.resolve_crate(name, item.span, dep_kind)?; - let path_len = definitions.def_path(def_id).data.len(); + let path_len = self.definitions.def_path(def_id).data.len(); self.update_extern_crate( cnum, ExternCrate { diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs index 4fa440c7ca6..7601f6bd322 100644 --- a/compiler/rustc_metadata/src/fs.rs +++ b/compiler/rustc_metadata/src/fs.rs @@ -61,8 +61,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) { .unwrap_or(MetadataKind::None); let crate_name = tcx.crate_name(LOCAL_CRATE); - let out_filename = - filename_for_metadata(tcx.sess, crate_name.as_str(), tcx.output_filenames(())); + let out_filename = filename_for_metadata(tcx.sess, crate_name, tcx.output_filenames(())); // To avoid races with another rustc process scanning the output directory, // we need to write the file somewhere else and atomically move it to its // final destination, with an `fs::rename` call. In order for the rename to diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 33cce0a411e..9d0ccfeb168 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -629,6 +629,9 @@ impl CrateStore for CStore { fn as_any(&self) -> &dyn Any { self } + fn untracked_as_any(&mut self) -> &mut dyn Any { + self + } fn crate_name(&self, cnum: CrateNum) -> Symbol { self.get_crate_data(cnum).root.name diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 1bd8f953508..0450abed51b 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -14,7 +14,7 @@ use rustc_index::vec::Idx; use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use rustc_target::spec::abi::Abi; #[inline] @@ -1162,7 +1162,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { .filter_map(|(def_id, info)| { let _ = info.as_owner()?; let def_path_hash = definitions.def_path_hash(def_id); - let span = resolutions.source_span.get(def_id).unwrap_or(&DUMMY_SP); + let span = tcx.source_span(def_id); debug_assert_eq!(span.parent(), None); Some((def_path_hash, span)) }) diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 02fd03c0283..3f6e29ad611 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -141,8 +141,6 @@ pub fn provide(providers: &mut Providers) { providers.hir_attrs = |tcx, id| { tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs) }; - providers.source_span = - |tcx, def_id| tcx.resolutions(()).source_span.get(def_id).copied().unwrap_or(DUMMY_SP); providers.def_span = |tcx, def_id| { let def_id = def_id.expect_local(); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 7d2a6bda569..99e59c770d7 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -6,6 +6,7 @@ use super::{BasicBlock, Constant, Field, Local, SwitchTargets, UserTypeProjection}; use crate::mir::coverage::{CodeRegion, CoverageKind}; +use crate::traits::Reveal; use crate::ty::adjustment::PointerCast; use crate::ty::subst::SubstsRef; use crate::ty::{self, List, Ty}; @@ -100,6 +101,13 @@ impl MirPhase { MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized", } } + + pub fn reveal(&self) -> Reveal { + match *self { + MirPhase::Built | MirPhase::Analysis(_) => Reveal::UserFacing, + MirPhase::Runtime(_) => Reveal::All, + } + } } /// See [`MirPhase::Analysis`]. @@ -400,7 +408,7 @@ impl std::fmt::Display for NonDivergingIntrinsic<'_> { #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, Hash, HashStable)] #[rustc_pass_by_value] pub enum RetagKind { - /// The initial retag when entering a function. + /// The initial retag of arguments when entering a function. FnEntry, /// Retag preparing for a two-phase borrow. TwoPhase, @@ -518,12 +526,6 @@ pub enum TerminatorKind<'tcx> { SwitchInt { /// The discriminant value being tested. discr: Operand<'tcx>, - - /// The type of value being tested. - /// This is always the same as the type of `discr`. - /// FIXME: remove this redundant information. Currently, it is relied on by pretty-printing. - switch_ty: Ty<'tcx>, - targets: SwitchTargets, }, diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 4ea333cff7d..013a1bccd3b 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -1,6 +1,3 @@ -use crate::mir; -use crate::mir::interpret::Scalar; -use crate::ty::{self, Ty, TyCtxt}; use smallvec::{smallvec, SmallVec}; use super::{BasicBlock, InlineAsmOperand, Operand, SourceInfo, TerminatorKind}; @@ -131,17 +128,8 @@ impl<'tcx> Terminator<'tcx> { } impl<'tcx> TerminatorKind<'tcx> { - pub fn if_( - tcx: TyCtxt<'tcx>, - cond: Operand<'tcx>, - t: BasicBlock, - f: BasicBlock, - ) -> TerminatorKind<'tcx> { - TerminatorKind::SwitchInt { - discr: cond, - switch_ty: tcx.types.bool, - targets: SwitchTargets::static_if(0, f, t), - } + pub fn if_(cond: Operand<'tcx>, t: BasicBlock, f: BasicBlock) -> TerminatorKind<'tcx> { + TerminatorKind::SwitchInt { discr: cond, targets: SwitchTargets::static_if(0, f, t) } } pub fn successors(&self) -> Successors<'_> { @@ -264,11 +252,9 @@ impl<'tcx> TerminatorKind<'tcx> { } } - pub fn as_switch(&self) -> Option<(&Operand<'tcx>, Ty<'tcx>, &SwitchTargets)> { + pub fn as_switch(&self) -> Option<(&Operand<'tcx>, &SwitchTargets)> { match self { - TerminatorKind::SwitchInt { discr, switch_ty, targets } => { - Some((discr, *switch_ty, targets)) - } + TerminatorKind::SwitchInt { discr, targets } => Some((discr, targets)), _ => None, } } @@ -403,21 +389,12 @@ impl<'tcx> TerminatorKind<'tcx> { match *self { Return | Resume | Abort | Unreachable | GeneratorDrop => vec![], Goto { .. } => vec!["".into()], - SwitchInt { ref targets, switch_ty, .. } => ty::tls::with(|tcx| { - let param_env = ty::ParamEnv::empty(); - let switch_ty = tcx.lift(switch_ty).unwrap(); - let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size; - targets - .values - .iter() - .map(|&u| { - mir::ConstantKind::from_scalar(tcx, Scalar::from_uint(u, size), switch_ty) - .to_string() - .into() - }) - .chain(iter::once("otherwise".into())) - .collect() - }), + SwitchInt { ref targets, .. } => targets + .values + .iter() + .map(|&u| Cow::Owned(u.to_string())) + .chain(iter::once("otherwise".into())) + .collect(), Call { target: Some(_), cleanup: Some(_), .. } => { vec!["return".into(), "unwind".into()] } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index b21f50ae5ea..2ee3f551529 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -477,11 +477,9 @@ macro_rules! make_mir_visitor { TerminatorKind::SwitchInt { discr, - switch_ty, targets: _ } => { self.visit_operand(discr, location); - self.visit_ty($(& $mutability)? *switch_ty, TyContext::Location(location)); } TerminatorKind::Drop { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f2f2b22f52a..ab512804330 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -43,6 +43,8 @@ rustc_queries! { /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside /// of rustc_middle::hir::source_map. query source_span(key: LocalDefId) -> Span { + // Accesses untracked data + eval_always desc { "getting the source span" } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index af573376a26..7d4971d1e9e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -35,7 +35,7 @@ use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{self, Lock, Lrc, ReadGuard, RwLock, WorkerLocal}; +use rustc_data_structures::sync::{self, Lock, Lrc, ReadGuard, WorkerLocal}; use rustc_data_structures::unord::UnordSet; use rustc_data_structures::vec_map::VecMap; use rustc_errors::{ @@ -59,7 +59,7 @@ use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_session::config::{CrateType, OutputFilenames}; -use rustc_session::cstore::CrateStoreDyn; +use rustc_session::cstore::{CrateStoreDyn, Untracked}; use rustc_session::lint::Lint; use rustc_session::Limit; use rustc_session::Session; @@ -182,20 +182,12 @@ impl<'tcx> CtxtInterners<'tcx> { /// Interns a type. #[allow(rustc::usage_of_ty_tykind)] #[inline(never)] - fn intern_ty( - &self, - kind: TyKind<'tcx>, - sess: &Session, - definitions: &rustc_hir::definitions::Definitions, - cstore: &CrateStoreDyn, - source_span: &IndexVec<LocalDefId, Span>, - ) -> Ty<'tcx> { + fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> { Ty(Interned::new_unchecked( self.type_ .intern(kind, |kind| { let flags = super::flags::FlagComputation::for_kind(&kind); - let stable_hash = - self.stable_hash(&flags, sess, definitions, cstore, source_span, &kind); + let stable_hash = self.stable_hash(&flags, sess, untracked, &kind); InternedInSet(self.arena.alloc(WithCachedTypeInfo { internee: kind, @@ -212,9 +204,7 @@ impl<'tcx> CtxtInterners<'tcx> { &self, flags: &ty::flags::FlagComputation, sess: &'a Session, - definitions: &'a rustc_hir::definitions::Definitions, - cstore: &'a CrateStoreDyn, - source_span: &'a IndexVec<LocalDefId, Span>, + untracked: &'a Untracked, val: &T, ) -> Fingerprint { // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them. @@ -223,7 +213,7 @@ impl<'tcx> CtxtInterners<'tcx> { Fingerprint::ZERO } else { let mut hasher = StableHasher::new(); - let mut hcx = StableHashingContext::new(sess, definitions, cstore, source_span); + let mut hcx = StableHashingContext::new(sess, untracked); val.hash_stable(&mut hcx, &mut hasher); hasher.finish() } @@ -234,17 +224,14 @@ impl<'tcx> CtxtInterners<'tcx> { &self, kind: Binder<'tcx, PredicateKind<'tcx>>, sess: &Session, - definitions: &rustc_hir::definitions::Definitions, - cstore: &CrateStoreDyn, - source_span: &IndexVec<LocalDefId, Span>, + untracked: &Untracked, ) -> Predicate<'tcx> { Predicate(Interned::new_unchecked( self.predicate .intern(kind, |kind| { let flags = super::flags::FlagComputation::for_predicate(kind); - let stable_hash = - self.stable_hash(&flags, sess, definitions, cstore, source_span, &kind); + let stable_hash = self.stable_hash(&flags, sess, untracked, &kind); InternedInSet(self.arena.alloc(WithCachedTypeInfo { internee: kind, @@ -962,11 +949,9 @@ impl<'tcx> CommonTypes<'tcx> { fn new( interners: &CtxtInterners<'tcx>, sess: &Session, - definitions: &rustc_hir::definitions::Definitions, - cstore: &CrateStoreDyn, - source_span: &IndexVec<LocalDefId, Span>, + untracked: &Untracked, ) -> CommonTypes<'tcx> { - let mk = |ty| interners.intern_ty(ty, sess, definitions, cstore, source_span); + let mk = |ty| interners.intern_ty(ty, sess, untracked); CommonTypes { unit: mk(Tuple(List::empty())), @@ -1112,8 +1097,7 @@ pub struct GlobalCtxt<'tcx> { /// Common consts, pre-interned for your convenience. pub consts: CommonConsts<'tcx>, - definitions: RwLock<Definitions>, - + untracked: Untracked, /// Output of the resolver. pub(crate) untracked_resolutions: ty::ResolverGlobalCtxt, /// The entire crate as AST. This field serves as the input for the hir_crate query, @@ -1278,28 +1262,21 @@ impl<'tcx> TyCtxt<'tcx> { lint_store: Lrc<dyn Any + sync::Send + sync::Sync>, arena: &'tcx WorkerLocal<Arena<'tcx>>, hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>, - definitions: Definitions, untracked_resolutions: ty::ResolverGlobalCtxt, + untracked: Untracked, krate: Lrc<ast::Crate>, dep_graph: DepGraph, on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>, queries: &'tcx dyn query::QueryEngine<'tcx>, query_kinds: &'tcx [DepKindStruct<'tcx>], - crate_name: &str, + crate_name: Symbol, output_filenames: OutputFilenames, ) -> GlobalCtxt<'tcx> { let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| { s.emit_fatal(err); }); let interners = CtxtInterners::new(arena); - let common_types = CommonTypes::new( - &interners, - s, - &definitions, - &*untracked_resolutions.cstore, - // This is only used to create a stable hashing context. - &untracked_resolutions.source_span, - ); + let common_types = CommonTypes::new(&interners, s, &untracked); let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); @@ -1310,11 +1287,11 @@ impl<'tcx> TyCtxt<'tcx> { hir_arena, interners, dep_graph, - definitions: RwLock::new(definitions), prof: s.prof.clone(), types: common_types, lifetimes: common_lifetimes, consts: common_consts, + untracked, untracked_resolutions, untracked_crate: Steal::new(krate), on_disk_cache, @@ -1325,7 +1302,7 @@ impl<'tcx> TyCtxt<'tcx> { pred_rcache: Default::default(), selection_cache: Default::default(), evaluation_cache: Default::default(), - crate_name: Symbol::intern(crate_name), + crate_name, data_layout, alloc_map: Lock::new(interpret::AllocMap::new()), output_filenames: Arc::new(output_filenames), @@ -1428,7 +1405,7 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(id) = id.as_local() { self.definitions_untracked().def_key(id) } else { - self.untracked_resolutions.cstore.def_key(id) + self.untracked.cstore.def_key(id) } } @@ -1442,7 +1419,7 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(id) = id.as_local() { self.definitions_untracked().def_path(id) } else { - self.untracked_resolutions.cstore.def_path(id) + self.untracked.cstore.def_path(id) } } @@ -1452,7 +1429,7 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(def_id) = def_id.as_local() { self.definitions_untracked().def_path_hash(def_id) } else { - self.untracked_resolutions.cstore.def_path_hash(def_id) + self.untracked.cstore.def_path_hash(def_id) } } @@ -1461,7 +1438,7 @@ impl<'tcx> TyCtxt<'tcx> { if crate_num == LOCAL_CRATE { self.sess.local_stable_crate_id() } else { - self.untracked_resolutions.cstore.stable_crate_id(crate_num) + self.untracked.cstore.stable_crate_id(crate_num) } } @@ -1472,7 +1449,7 @@ impl<'tcx> TyCtxt<'tcx> { if stable_crate_id == self.sess.local_stable_crate_id() { LOCAL_CRATE } else { - self.untracked_resolutions.cstore.stable_crate_id_to_crate_num(stable_crate_id) + self.untracked.cstore.stable_crate_id_to_crate_num(stable_crate_id) } } @@ -1487,11 +1464,11 @@ impl<'tcx> TyCtxt<'tcx> { // If this is a DefPathHash from the local crate, we can look up the // DefId in the tcx's `Definitions`. if stable_crate_id == self.sess.local_stable_crate_id() { - self.definitions.read().local_def_path_hash_to_def_id(hash, err).to_def_id() + self.untracked.definitions.read().local_def_path_hash_to_def_id(hash, err).to_def_id() } else { // If this is a DefPathHash from an upstream crate, let the CrateStore map // it to a DefId. - let cstore = &*self.untracked_resolutions.cstore; + let cstore = &*self.untracked.cstore; let cnum = cstore.stable_crate_id_to_crate_num(stable_crate_id); cstore.def_path_hash_to_def_id(cnum, hash) } @@ -1505,7 +1482,7 @@ impl<'tcx> TyCtxt<'tcx> { let (crate_name, stable_crate_id) = if def_id.is_local() { (self.crate_name, self.sess.local_stable_crate_id()) } else { - let cstore = &*self.untracked_resolutions.cstore; + let cstore = &*self.untracked.cstore; (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate)) }; @@ -1547,7 +1524,7 @@ impl<'tcx> TyCtxtAt<'tcx> { // This is fine because: // - those queries are `eval_always` so we won't miss their result changing; // - this write will have happened before these queries are called. - let key = self.definitions.write().create_def(parent, data); + let key = self.untracked.definitions.write().create_def(parent, data); let feed = TyCtxtFeed { tcx: self.tcx, key }; feed.def_span(self.span); @@ -1561,7 +1538,7 @@ impl<'tcx> TyCtxt<'tcx> { // definitions change. self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); - let definitions = &self.definitions; + let definitions = &self.untracked.definitions; std::iter::from_generator(|| { let mut i = 0; @@ -1585,7 +1562,7 @@ impl<'tcx> TyCtxt<'tcx> { // Leak a read lock once we start iterating on definitions, to prevent adding new ones // while iterating. If some query needs to add definitions, it should be `ensure`d above. - let definitions = self.definitions.leak(); + let definitions = self.untracked.definitions.leak(); definitions.def_path_table() } @@ -1597,28 +1574,28 @@ impl<'tcx> TyCtxt<'tcx> { self.ensure().hir_crate(()); // Leak a read lock once we start iterating on definitions, to prevent adding new ones // while iterating. If some query needs to add definitions, it should be `ensure`d above. - let definitions = self.definitions.leak(); + let definitions = self.untracked.definitions.leak(); definitions.def_path_hash_to_def_index_map() } /// Note that this is *untracked* and should only be used within the query /// system if the result is otherwise tracked through queries pub fn cstore_untracked(self) -> &'tcx CrateStoreDyn { - &*self.untracked_resolutions.cstore + &*self.untracked.cstore } /// Note that this is *untracked* and should only be used within the query /// system if the result is otherwise tracked through queries #[inline] pub fn definitions_untracked(self) -> ReadGuard<'tcx, Definitions> { - self.definitions.read() + self.untracked.definitions.read() } /// Note that this is *untracked* and should only be used within the query /// system if the result is otherwise tracked through queries #[inline] pub fn source_span_untracked(self, def_id: LocalDefId) -> Span { - self.untracked_resolutions.source_span.get(def_id).copied().unwrap_or(DUMMY_SP) + self.untracked.source_span.get(def_id).copied().unwrap_or(DUMMY_SP) } #[inline(always)] @@ -1626,14 +1603,7 @@ impl<'tcx> TyCtxt<'tcx> { self, f: impl FnOnce(StableHashingContext<'_>) -> R, ) -> R { - let definitions = self.definitions_untracked(); - let hcx = StableHashingContext::new( - self.sess, - &*definitions, - &*self.untracked_resolutions.cstore, - &self.untracked_resolutions.source_span, - ); - f(hcx) + f(StableHashingContext::new(self.sess, &self.untracked)) } pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult { @@ -2427,10 +2397,8 @@ impl<'tcx> TyCtxt<'tcx> { self.interners.intern_ty( st, self.sess, - &self.definitions.read(), - &*self.untracked_resolutions.cstore, // This is only used to create a stable hashing context. - &self.untracked_resolutions.source_span, + &self.untracked, ) } @@ -2439,10 +2407,8 @@ impl<'tcx> TyCtxt<'tcx> { self.interners.intern_predicate( binder, self.sess, - &self.definitions.read(), - &*self.untracked_resolutions.cstore, // This is only used to create a stable hashing context. - &self.untracked_resolutions.source_span, + &self.untracked, ) } @@ -3124,4 +3090,6 @@ pub fn provide(providers: &mut ty::query::Providers) { // We want to check if the panic handler was defined in this crate tcx.lang_items().panic_impl().map_or(false, |did| did.is_local()) }; + providers.source_span = + |tcx, def_id| tcx.untracked.source_span.get(def_id).copied().unwrap_or(DUMMY_SP); } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index d83e17574a0..aa61c39b8d8 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -986,23 +986,32 @@ fn foo(&self) -> Self::T { String::new() } } pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) { - let length_limit = 50; - let type_limit = 4; + let width = self.sess.diagnostic_width(); + let length_limit = width.saturating_sub(30); + let mut type_limit = 50; let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS) .pretty_print_type(ty) .expect("could not write to `String`") .into_buffer(); - if regular.len() <= length_limit { + if regular.len() <= width { return (regular, None); } - let short = FmtPrinter::new_with_limit( - self, - hir::def::Namespace::TypeNS, - rustc_session::Limit(type_limit), - ) - .pretty_print_type(ty) - .expect("could not write to `String`") - .into_buffer(); + let mut short; + loop { + // Look for the longest properly trimmed path that still fits in lenght_limit. + short = FmtPrinter::new_with_limit( + self, + hir::def::Namespace::TypeNS, + rustc_session::Limit(type_limit), + ) + .pretty_print_type(ty) + .expect("could not write to `String`") + .into_buffer(); + if short.len() <= length_limit || type_limit == 0 { + break; + } + type_limit -= 1; + } if regular == short { return (regular, None); } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 48329da3e63..2e70ac256a7 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -234,6 +234,15 @@ impl<'tcx> Generics { } } + pub fn params_to(&'tcx self, param_index: usize, tcx: TyCtxt<'tcx>) -> &'tcx [GenericParamDef] { + if let Some(index) = param_index.checked_sub(self.parent_count) { + &self.params[..index] + } else { + tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?")) + .params_to(param_index, tcx) + } + } + /// Returns the `GenericParamDef` associated with this `EarlyBoundRegion`. pub fn region_param( &'tcx self, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c062e508ee3..659d99f025d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -40,13 +40,12 @@ use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap}; -use rustc_hir::definitions::Definitions; use rustc_hir::Node; use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::{Decodable, Encodable}; -use rustc_session::cstore::CrateStoreDyn; +use rustc_session::cstore::Untracked; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{ExpnId, Span}; @@ -150,21 +149,18 @@ mod sty; pub type RegisteredTools = FxHashSet<Ident>; pub struct ResolverOutputs { - pub definitions: Definitions, pub global_ctxt: ResolverGlobalCtxt, pub ast_lowering: ResolverAstLowering, + pub untracked: Untracked, } #[derive(Debug)] pub struct ResolverGlobalCtxt { - pub cstore: Box<CrateStoreDyn>, pub visibilities: FxHashMap<LocalDefId, Visibility>, /// This field is used to decide whether we should make `PRIVATE_IN_PUBLIC` a hard error. pub has_pub_restricted: bool, /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>, - /// Reference span for definitions. - pub source_span: IndexVec<LocalDefId, Span>, pub effective_visibilities: EffectiveVisibilities, pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>, pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 47c1ce80756..9ea8dc6e69f 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1,6 +1,7 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use crate::mir; use crate::ty::layout::IntegerExt; use crate::ty::{ self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -15,6 +16,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_index::bit_set::GrowableBitSet; +use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_span::{sym, DUMMY_SP}; use rustc_target::abi::{Integer, IntegerType, Size, TargetDataLayout}; @@ -692,6 +694,80 @@ impl<'tcx> TyCtxt<'tcx> { pub fn bound_impl_subject(self, def_id: DefId) -> ty::EarlyBinder<ty::ImplSubject<'tcx>> { ty::EarlyBinder(self.impl_subject(def_id)) } + + /// Returns names of captured upvars for closures and generators. + /// + /// Here are some examples: + /// - `name__field1__field2` when the upvar is captured by value. + /// - `_ref__name__field` when the upvar is captured by reference. + /// + /// For generators this only contains upvars that are shared by all states. + pub fn closure_saved_names_of_captured_variables( + self, + def_id: DefId, + ) -> SmallVec<[String; 16]> { + let body = self.optimized_mir(def_id); + + body.var_debug_info + .iter() + .filter_map(|var| { + let is_ref = match var.value { + mir::VarDebugInfoContents::Place(place) + if place.local == mir::Local::new(1) => + { + // The projection is either `[.., Field, Deref]` or `[.., Field]`. It + // implies whether the variable is captured by value or by reference. + matches!(place.projection.last().unwrap(), mir::ProjectionElem::Deref) + } + _ => return None, + }; + let prefix = if is_ref { "_ref__" } else { "" }; + Some(prefix.to_owned() + var.name.as_str()) + }) + .collect() + } + + // FIXME(eddyb) maybe precompute this? Right now it's computed once + // per generator monomorphization, but it doesn't depend on substs. + pub fn generator_layout_and_saved_local_names( + self, + def_id: DefId, + ) -> ( + &'tcx ty::GeneratorLayout<'tcx>, + IndexVec<mir::GeneratorSavedLocal, Option<rustc_span::Symbol>>, + ) { + let tcx = self; + let body = tcx.optimized_mir(def_id); + let generator_layout = body.generator_layout().unwrap(); + let mut generator_saved_local_names = + IndexVec::from_elem(None, &generator_layout.field_tys); + + let state_arg = mir::Local::new(1); + for var in &body.var_debug_info { + let mir::VarDebugInfoContents::Place(place) = &var.value else { continue }; + if place.local != state_arg { + continue; + } + match place.projection[..] { + [ + // Deref of the `Pin<&mut Self>` state argument. + mir::ProjectionElem::Field(..), + mir::ProjectionElem::Deref, + // Field of a variant of the state. + mir::ProjectionElem::Downcast(_, variant), + mir::ProjectionElem::Field(field, _), + ] => { + let name = &mut generator_saved_local_names + [generator_layout.variant_fields[variant][field]]; + if name.is_none() { + name.replace(var.name); + } + } + _ => {} + } + } + (generator_layout, generator_saved_local_names) + } } struct OpaqueTypeExpander<'tcx> { diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 218a26e6279..38b1fa91d0a 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -183,7 +183,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { LogicalOp::And => (else_block, shortcircuit_block), LogicalOp::Or => (shortcircuit_block, else_block), }; - let term = TerminatorKind::if_(this.tcx, lhs, blocks.0, blocks.1); + let term = TerminatorKind::if_(lhs, blocks.0, blocks.1); this.cfg.terminate(block, source_info, term); this.cfg.push_assign_constant( diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 691cbee2c73..e90db2c7d05 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let then_block = this.cfg.start_new_block(); let else_block = this.cfg.start_new_block(); - let term = TerminatorKind::if_(this.tcx, operand, then_block, else_block); + let term = TerminatorKind::if_(operand, then_block, else_block); let source_info = this.source_info(expr_span); this.cfg.terminate(block, source_info, term); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 58513bde2aa..6d5a98342d2 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -203,7 +203,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.source_info(match_start_span), TerminatorKind::SwitchInt { discr: Operand::Move(discr), - switch_ty: discr_ty, targets: switch_targets, }, ); @@ -221,7 +220,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { 0 => (second_bb, first_bb), v => span_bug!(test.span, "expected boolean value but got {:?}", v), }; - TerminatorKind::if_(self.tcx, Operand::Copy(place), true_bb, false_bb) + TerminatorKind::if_(Operand::Copy(place), true_bb, false_bb) } else { // The switch may be inexhaustive so we have a catch all block debug_assert_eq!(options.len() + 1, target_blocks.len()); @@ -232,7 +231,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); TerminatorKind::SwitchInt { discr: Operand::Copy(place), - switch_ty, targets: switch_targets, } }; @@ -378,7 +376,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate( block, source_info, - TerminatorKind::if_(self.tcx, Operand::Move(result), success_block, fail_block), + TerminatorKind::if_(Operand::Move(result), success_block, fail_block), ); } @@ -482,7 +480,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate( eq_block, source_info, - TerminatorKind::if_(self.tcx, Operand::Move(eq_result), success_block, fail_block), + TerminatorKind::if_(Operand::Move(eq_result), success_block, fail_block), ); } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index ce87a1916b4..8610792c0eb 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -596,7 +596,6 @@ where source_info: self.source_info, kind: TerminatorKind::SwitchInt { discr: Operand::Move(discr), - switch_ty: discr_ty, targets: SwitchTargets::new( values.iter().copied().zip(blocks.iter().copied()), *blocks.last().unwrap(), @@ -716,7 +715,7 @@ where is_cleanup: unwind.is_cleanup(), terminator: Some(Terminator { source_info: self.source_info, - kind: TerminatorKind::if_(tcx, move_(can_go), succ, drop_block), + kind: TerminatorKind::if_(move_(can_go), succ, drop_block), }), }; let loop_block = self.elaborator.patch().new_block(loop_block); @@ -781,7 +780,6 @@ where source_info: self.source_info, kind: TerminatorKind::SwitchInt { discr: move_(elem_size), - switch_ty: tcx.types.usize, targets: SwitchTargets::static_if( 0, self.drop_loop_pair(ety, false, len), @@ -1021,7 +1019,7 @@ where DropStyle::Static => on_set, DropStyle::Conditional | DropStyle::Open => { let flag = self.elaborator.get_drop_flag(self.path).unwrap(); - let term = TerminatorKind::if_(self.tcx(), flag, on_set, on_unset); + let term = TerminatorKind::if_(flag, on_set, on_unset); self.new_block(unwind, term) } } diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 5c77f3ea395..5ff6b9e7e69 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -261,7 +261,7 @@ impl Direction for Backward { propagate(pred, &tmp); } - mir::TerminatorKind::SwitchInt { targets: _, ref discr, switch_ty: _ } => { + mir::TerminatorKind::SwitchInt { targets: _, ref discr } => { let mut applier = BackwardSwitchIntEdgeEffectsApplier { body, pred, @@ -577,7 +577,7 @@ impl Direction for Forward { } } - SwitchInt { ref targets, ref discr, switch_ty: _ } => { + SwitchInt { ref targets, ref discr } => { let mut applier = ForwardSwitchIntEdgeEffectsApplier { exit_state, targets, diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 036b5589849..3d22035f078 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -10,16 +10,6 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; pub struct AddRetag; -/// Determines whether this place is "stable": Whether, if we evaluate it again -/// after the assignment, we can be sure to obtain the same place value. -/// (Concurrent accesses by other threads are no problem as these are anyway non-atomic -/// copies. Data races are UB.) -fn is_stable(place: PlaceRef<'_>) -> bool { - // Which place this evaluates to can change with any memory write, - // so cannot assume deref to be stable. - !place.has_deref() -} - /// Determine whether this type may contain a reference (or box), and thus needs retagging. /// We will only recurse `depth` times into Tuples/ADTs to bound the cost of this. fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> bool { @@ -69,22 +59,10 @@ impl<'tcx> MirPass<'tcx> for AddRetag { let basic_blocks = body.basic_blocks.as_mut(); let local_decls = &body.local_decls; let needs_retag = |place: &Place<'tcx>| { - // FIXME: Instead of giving up for unstable places, we should introduce - // a temporary and retag on that. - is_stable(place.as_ref()) + !place.has_deref() // we're not eally interested in stores to "outside" locations, they are hard to keep track of anyway && may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx) && !local_decls[place.local].is_deref_temp() }; - let place_base_raw = |place: &Place<'tcx>| { - // If this is a `Deref`, get the type of what we are deref'ing. - if place.has_deref() { - let ty = &local_decls[place.local].ty; - ty.is_unsafe_ptr() - } else { - // Not a deref, and thus not raw. - false - } - }; // PART 1 // Retag arguments at the beginning of the start block. @@ -108,7 +86,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag { } // PART 2 - // Retag return values of functions. Also escape-to-raw the argument of `drop`. + // Retag return values of functions. // We collect the return destinations because we cannot mutate while iterating. let returns = basic_blocks .iter_mut() @@ -140,30 +118,25 @@ impl<'tcx> MirPass<'tcx> for AddRetag { } // PART 3 - // Add retag after assignment. + // Add retag after assignments where data "enters" this function: the RHS is behind a deref and the LHS is not. for block_data in basic_blocks { // We want to insert statements as we iterate. To this end, we // iterate backwards using indices. for i in (0..block_data.statements.len()).rev() { let (retag_kind, place) = match block_data.statements[i].kind { - // Retag-as-raw after escaping to a raw pointer, if the referent - // is not already a raw pointer. - StatementKind::Assign(box (lplace, Rvalue::AddressOf(_, ref rplace))) - if !place_base_raw(rplace) => - { - (RetagKind::Raw, lplace) - } // Retag after assignments of reference type. StatementKind::Assign(box (ref place, ref rvalue)) if needs_retag(place) => { - let kind = match rvalue { - Rvalue::Ref(_, borrow_kind, _) - if borrow_kind.allows_two_phase_borrow() => - { - RetagKind::TwoPhase - } - _ => RetagKind::Default, + let add_retag = match rvalue { + // Ptr-creating operations already do their own internal retagging, no + // need to also add a retag statement. + Rvalue::Ref(..) | Rvalue::AddressOf(..) => false, + _ => true, }; - (kind, *place) + if add_retag { + (RetagKind::Default, *place) + } else { + continue; + } } // Do nothing for the rest _ => continue, diff --git a/compiler/rustc_mir_transform/src/const_goto.rs b/compiler/rustc_mir_transform/src/const_goto.rs index 0a305a40209..40eefda4f07 100644 --- a/compiler/rustc_mir_transform/src/const_goto.rs +++ b/compiler/rustc_mir_transform/src/const_goto.rs @@ -82,8 +82,9 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> { } let target_bb_terminator = target_bb.terminator(); - let (discr, switch_ty, targets) = target_bb_terminator.kind.as_switch()?; + let (discr, targets) = target_bb_terminator.kind.as_switch()?; if discr.place() == Some(*place) { + let switch_ty = place.ty(self.body.local_decls(), self.tcx).ty; // We now know that the Switch matches on the const place, and it is statementless // Now find which value in the Switch matches the const value. let const_value = diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 9c9ed5fa510..eba6a2b34e4 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -37,7 +37,7 @@ use rustc_data_structures::graph::WithSuccessors; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty; use rustc_span::{self, BytePos, Pos, Span, DUMMY_SP}; // All `TEMP_BLOCK` targets should be replaced before calling `to_body() -> mir::Body`. @@ -47,7 +47,6 @@ struct MockBlocks<'tcx> { blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>, dummy_place: Place<'tcx>, next_local: usize, - bool_ty: Ty<'tcx>, } impl<'tcx> MockBlocks<'tcx> { @@ -56,7 +55,6 @@ impl<'tcx> MockBlocks<'tcx> { blocks: IndexVec::new(), dummy_place: Place { local: RETURN_PLACE, projection: ty::List::empty() }, next_local: 0, - bool_ty: TyCtxt::BOOL_TY_FOR_UNIT_TESTING, } } @@ -157,7 +155,6 @@ impl<'tcx> MockBlocks<'tcx> { fn switchint(&mut self, some_from_block: Option<BasicBlock>) -> BasicBlock { let switchint_kind = TerminatorKind::SwitchInt { discr: Operand::Move(Place::from(self.new_temp())), - switch_ty: self.bool_ty, // just a dummy value targets: SwitchTargets::static_if(0, TEMP_BLOCK, TEMP_BLOCK), }; self.add_block_from(some_from_block, switchint_kind) diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index 32e738bbcea..8a7b027ddda 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -121,7 +121,6 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { let TerminatorKind::SwitchInt { discr: parent_op, - switch_ty: parent_ty, targets: parent_targets } = &bbs[parent].terminator().kind else { unreachable!() @@ -132,6 +131,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { Operand::Copy(x) => Operand::Copy(*x), Operand::Constant(x) => Operand::Constant(x.clone()), }; + let parent_ty = parent_op.ty(body.local_decls(), tcx); let statements_before = bbs[parent].statements.len(); let parent_end = Location { block: parent, statement_index: statements_before }; @@ -153,7 +153,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { // create temp to store inequality comparison between the two discriminants, `_t` in // example above let nequal = BinOp::Ne; - let comp_res_type = nequal.ty(tcx, *parent_ty, opt_data.child_ty); + let comp_res_type = nequal.ty(tcx, parent_ty, opt_data.child_ty); let comp_temp = patch.new_temp(comp_res_type, opt_data.child_source.span); patch.add_statement(parent_end, StatementKind::StorageLive(comp_temp)); @@ -181,7 +181,6 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { kind: TerminatorKind::SwitchInt { // switch on the first discriminant, so we can mark the second one as dead discr: parent_op, - switch_ty: opt_data.child_ty, targets: eq_targets, }, })); @@ -193,12 +192,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { let false_case = eq_bb; patch.patch_terminator( parent, - TerminatorKind::if_( - tcx, - Operand::Move(Place::from(comp_temp)), - true_case, - false_case, - ), + TerminatorKind::if_(Operand::Move(Place::from(comp_temp)), true_case, false_case), ); // generate StorageDead for the second_discriminant_temp not in use anymore @@ -319,11 +313,11 @@ fn evaluate_candidate<'tcx>( let bbs = &body.basic_blocks; let TerminatorKind::SwitchInt { targets, - switch_ty: parent_ty, - .. + discr: parent_discr, } = &bbs[parent].terminator().kind else { return None }; + let parent_ty = parent_discr.ty(body.local_decls(), tcx); let parent_dest = { let poss = targets.otherwise(); // If the fallthrough on the parent is trivially unreachable, we can let the @@ -339,12 +333,12 @@ fn evaluate_candidate<'tcx>( let (_, child) = targets.iter().next()?; let child_terminator = &bbs[child].terminator(); let TerminatorKind::SwitchInt { - switch_ty: child_ty, targets: child_targets, - .. + discr: child_discr, } = &child_terminator.kind else { return None }; + let child_ty = child_discr.ty(body.local_decls(), tcx); if child_ty != parent_ty { return None; } @@ -372,7 +366,7 @@ fn evaluate_candidate<'tcx>( Some(OptimizationData { destination, child_place: *child_place, - child_ty: *child_ty, + child_ty, child_source: child_terminator.source_info, }) } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 8922298ecaf..c08593afe9d 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -877,11 +877,7 @@ fn insert_switch<'tcx>( let (assign, discr) = transform.get_discr(body); let switch_targets = SwitchTargets::new(cases.iter().map(|(i, bb)| ((*i) as u128, *bb)), default_block); - let switch = TerminatorKind::SwitchInt { - discr: Operand::Move(discr), - switch_ty: transform.discr_ty, - targets: switch_targets, - }; + let switch = TerminatorKind::SwitchInt { discr: Operand::Move(discr), targets: switch_targets }; let source_info = SourceInfo::outermost(body.span); body.basic_blocks_mut().raw.insert( @@ -985,16 +981,6 @@ fn create_generator_drop_shim<'tcx>( tcx.mk_ptr(ty::TypeAndMut { ty: gen_ty, mutbl: hir::Mutability::Mut }), source_info, ); - if tcx.sess.opts.unstable_opts.mir_emit_retag { - // Alias tracking must know we changed the type - body.basic_blocks_mut()[START_BLOCK].statements.insert( - 0, - Statement { - source_info, - kind: StatementKind::Retag(RetagKind::Raw, Box::new(Place::from(SELF_ARG))), - }, - ) - } // Make sure we remove dead blocks to remove // unrelated code from the resume part of the function diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index a0ba69c89b0..ce05db5b762 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -55,10 +55,9 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { continue; } - let (discr, val, switch_ty, first, second) = match bbs[bb_idx].terminator().kind { + let (discr, val, first, second) = match bbs[bb_idx].terminator().kind { TerminatorKind::SwitchInt { discr: ref discr @ (Operand::Copy(_) | Operand::Move(_)), - switch_ty, ref targets, .. } if targets.iter().len() == 1 => { @@ -66,7 +65,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { if target == targets.otherwise() { continue; } - (discr, value, switch_ty, target, targets.otherwise()) + (discr, value, target, targets.otherwise()) } // Only optimize switch int statements _ => continue, @@ -105,10 +104,11 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { } // Take ownership of items now that we know we can optimize. let discr = discr.clone(); + let discr_ty = discr.ty(&body.local_decls, tcx); // Introduce a temporary for the discriminant value. let source_info = bbs[bb_idx].terminator().source_info; - let discr_local = body.local_decls.push(LocalDecl::new(switch_ty, source_info.span)); + let discr_local = body.local_decls.push(LocalDecl::new(discr_ty, source_info.span)); // We already checked that first and second are different blocks, // and bb_idx has a different terminator from both of them. @@ -130,10 +130,10 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { (*f).clone() } else { // Different value between blocks. Make value conditional on switch condition. - let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size; + let size = tcx.layout_of(param_env.and(discr_ty)).unwrap().size; let const_cmp = Operand::const_from_scalar( tcx, - switch_ty, + discr_ty, rustc_const_eval::interpret::Scalar::from_uint(val, size), rustc_span::DUMMY_SP, ); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index a115bb2831a..f92a0e826dc 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -177,16 +177,6 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>) if ty.is_some() { // The first argument (index 0), but add 1 for the return value. let dropee_ptr = Place::from(Local::new(1 + 0)); - if tcx.sess.opts.unstable_opts.mir_emit_retag { - // Function arguments should be retagged, and we make this one raw. - body.basic_blocks_mut()[START_BLOCK].statements.insert( - 0, - Statement { - source_info, - kind: StatementKind::Retag(RetagKind::Raw, Box::new(dropee_ptr)), - }, - ); - } let patch = { let param_env = tcx.param_env_reveal_all_normalized(def_id); let mut elaborator = @@ -558,7 +548,6 @@ impl<'tcx> CloneShimBuilder<'tcx> { statements.push(statement); *kind = TerminatorKind::SwitchInt { discr: Operand::Move(temp), - switch_ty: discr_ty, targets: SwitchTargets::new(cases.into_iter(), unreachable), }; } diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index 405ebce4d22..8164b305278 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -24,12 +24,9 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { TerminatorKind::SwitchInt { - discr: Operand::Constant(ref c), - switch_ty, - ref targets, - .. + discr: Operand::Constant(ref c), ref targets, .. } => { - let constant = c.literal.try_eval_bits(tcx, param_env, switch_ty); + let constant = c.literal.try_eval_bits(tcx, param_env, c.ty()); if let Some(constant) = constant { let target = targets.target_for_value(constant); TerminatorKind::Goto { target } diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 321d8c63b6e..dcad1518eb6 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -127,11 +127,8 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral { let targets = SwitchTargets::new(iter::once((new_value, bb_cond)), bb_otherwise); let terminator = bb.terminator_mut(); - terminator.kind = TerminatorKind::SwitchInt { - discr: Operand::Move(opt.to_switch_on), - switch_ty: opt.branch_value_ty, - targets, - }; + terminator.kind = + TerminatorKind::SwitchInt { discr: Operand::Move(opt.to_switch_on), targets }; } for (idx, bb_idx) in storage_deads_to_remove { diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index 95fda2eafe8..06deca2fffb 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -76,7 +76,7 @@ where let terminator = match terminator_kind { // This will unconditionally run into an unreachable and is therefore unreachable as well. TerminatorKind::Goto { target } if is_unreachable(*target) => TerminatorKind::Unreachable, - TerminatorKind::SwitchInt { targets, discr, switch_ty } => { + TerminatorKind::SwitchInt { targets, discr } => { let otherwise = targets.otherwise(); // If all targets are unreachable, we can be unreachable as well. @@ -110,11 +110,7 @@ where return None; } - TerminatorKind::SwitchInt { - discr: discr.clone(), - switch_ty: *switch_ty, - targets: new_targets, - } + TerminatorKind::SwitchInt { discr: discr.clone(), targets: new_targets } } else { // If the otherwise branch is reachable, we don't want to delete any unreachable branches. return None; diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml index fcc68b3a219..72da398d3fc 100644 --- a/compiler/rustc_parse_format/Cargo.toml +++ b/compiler/rustc_parse_format/Cargo.toml @@ -5,3 +5,4 @@ edition = "2021" [dependencies] rustc_lexer = { path = "../rustc_lexer" } +rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 0113eb4e3d1..9cbe04c1288 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -58,13 +58,13 @@ impl InnerOffset { /// A piece is a portion of the format string which represents the next part /// to emit. These are emitted as a stream by the `Parser` class. -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub enum Piece<'a> { /// A literal string which should directly be emitted String(&'a str), /// This describes that formatting should process the next argument (as /// specified inside) for emission. - NextArgument(Argument<'a>), + NextArgument(Box<Argument<'a>>), } /// Representation of an argument specification. @@ -244,7 +244,7 @@ impl<'a> Iterator for Parser<'a> { } else { self.suggest_positional_arg_instead_of_captured_arg(arg); } - Some(NextArgument(arg)) + Some(NextArgument(Box::new(arg))) } } '}' => { @@ -908,5 +908,9 @@ fn find_skips_from_snippet( (skips, true) } +// Assert a reasonable size for `Piece` +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +rustc_data_structures::static_assert_size!(Piece<'_>, 16); + #[cfg(test)] mod tests; diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs index 3f9cb149b53..2992ba845ab 100644 --- a/compiler/rustc_parse_format/src/tests.rs +++ b/compiler/rustc_parse_format/src/tests.rs @@ -76,51 +76,51 @@ fn invalid_precision() { fn format_nothing() { same( "{}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 2 }, format: fmtdflt(), - })], + }))], ); } #[test] fn format_position() { same( "{3}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentIs(3), position_span: InnerSpan { start: 2, end: 3 }, format: fmtdflt(), - })], + }))], ); } #[test] fn format_position_nothing_else() { same( "{3:}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentIs(3), position_span: InnerSpan { start: 2, end: 3 }, format: fmtdflt(), - })], + }))], ); } #[test] fn format_named() { same( "{name}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentNamed("name"), position_span: InnerSpan { start: 2, end: 6 }, format: fmtdflt(), - })], + }))], ) } #[test] fn format_type() { same( "{3:x}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentIs(3), position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { @@ -134,14 +134,14 @@ fn format_type() { ty: "x", ty_span: None, }, - })], + }))], ); } #[test] fn format_align_fill() { same( "{3:>}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentIs(3), position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { @@ -155,11 +155,11 @@ fn format_align_fill() { ty: "", ty_span: None, }, - })], + }))], ); same( "{3:0<}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentIs(3), position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { @@ -173,11 +173,11 @@ fn format_align_fill() { ty: "", ty_span: None, }, - })], + }))], ); same( "{3:*<abcd}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentIs(3), position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { @@ -191,14 +191,14 @@ fn format_align_fill() { ty: "abcd", ty_span: Some(InnerSpan::new(6, 10)), }, - })], + }))], ); } #[test] fn format_counts() { same( "{:10x}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { @@ -212,11 +212,11 @@ fn format_counts() { ty: "x", ty_span: None, }, - })], + }))], ); same( "{:10$.10x}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { @@ -230,11 +230,11 @@ fn format_counts() { ty: "x", ty_span: None, }, - })], + }))], ); same( "{1:0$.10x}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentIs(1), position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { @@ -248,11 +248,11 @@ fn format_counts() { ty: "x", ty_span: None, }, - })], + }))], ); same( "{:.*x}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(1), position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { @@ -266,11 +266,11 @@ fn format_counts() { ty: "x", ty_span: None, }, - })], + }))], ); same( "{:.10$x}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { @@ -284,11 +284,11 @@ fn format_counts() { ty: "x", ty_span: None, }, - })], + }))], ); same( "{:a$.b$?}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { @@ -302,11 +302,11 @@ fn format_counts() { ty: "?", ty_span: None, }, - })], + }))], ); same( "{:.4}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { @@ -320,14 +320,14 @@ fn format_counts() { ty: "", ty_span: None, }, - })], + }))], ) } #[test] fn format_flags() { same( "{:-}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { @@ -341,11 +341,11 @@ fn format_flags() { ty: "", ty_span: None, }, - })], + }))], ); same( "{:+#}", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { @@ -359,7 +359,7 @@ fn format_flags() { ty: "", ty_span: None, }, - })], + }))], ); } #[test] @@ -368,7 +368,7 @@ fn format_mixture() { "abcd {3:x} efg", &[ String("abcd "), - NextArgument(Argument { + NextArgument(Box::new(Argument { position: ArgumentIs(3), position_span: InnerSpan { start: 7, end: 8 }, format: FormatSpec { @@ -382,7 +382,7 @@ fn format_mixture() { ty: "x", ty_span: None, }, - }), + })), String(" efg"), ], ); @@ -391,18 +391,18 @@ fn format_mixture() { fn format_whitespace() { same( "{ }", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 3 }, format: fmtdflt(), - })], + }))], ); same( "{ }", - &[NextArgument(Argument { + &[NextArgument(Box::new(Argument { position: ArgumentImplicitlyIs(0), position_span: InnerSpan { start: 2, end: 4 }, format: fmtdflt(), - })], + }))], ); } diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index 6378ec10875..163da59edd5 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -6,9 +6,8 @@ use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHa use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::definitions::{DefPathHash, Definitions}; -use rustc_index::vec::IndexVec; -use rustc_session::cstore::CrateStore; +use rustc_hir::definitions::DefPathHash; +use rustc_session::cstore::Untracked; use rustc_session::Session; use rustc_span::source_map::SourceMap; use rustc_span::symbol::Symbol; @@ -20,9 +19,7 @@ use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData, DUMM /// things (e.g., each `DefId`/`DefPath` is only hashed once). #[derive(Clone)] pub struct StableHashingContext<'a> { - definitions: &'a Definitions, - cstore: &'a dyn CrateStore, - source_span: &'a IndexVec<LocalDefId, Span>, + untracked: &'a Untracked, // The value of `-Z incremental-ignore-spans`. // This field should only be used by `unstable_opts_incremental_ignore_span` incremental_ignore_spans: bool, @@ -49,19 +46,12 @@ pub(super) enum BodyResolver<'tcx> { impl<'a> StableHashingContext<'a> { #[inline] - pub fn new( - sess: &'a Session, - definitions: &'a Definitions, - cstore: &'a dyn CrateStore, - source_span: &'a IndexVec<LocalDefId, Span>, - ) -> Self { + pub fn new(sess: &'a Session, untracked: &'a Untracked) -> Self { let hash_spans_initial = !sess.opts.unstable_opts.incremental_ignore_spans; StableHashingContext { body_resolver: BodyResolver::Forbidden, - definitions, - cstore, - source_span, + untracked, incremental_ignore_spans: sess.opts.unstable_opts.incremental_ignore_spans, caching_source_map: None, raw_source_map: sess.source_map(), @@ -100,13 +90,13 @@ impl<'a> StableHashingContext<'a> { if let Some(def_id) = def_id.as_local() { self.local_def_path_hash(def_id) } else { - self.cstore.def_path_hash(def_id) + self.untracked.cstore.def_path_hash(def_id) } } #[inline] pub fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash { - self.definitions.def_path_hash(def_id) + self.untracked.definitions.read().def_path_hash(def_id) } #[inline] @@ -156,7 +146,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { #[inline] fn def_span(&self, def_id: LocalDefId) -> Span { - *self.source_span.get(def_id).unwrap_or(&DUMMY_SP) + *self.untracked.source_span.get(def_id).unwrap_or(&DUMMY_SP) } #[inline] diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 9c90d67aadf..f4a6a08df1c 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -836,12 +836,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } else if orig_name == Some(kw::SelfLower) { Some(self.r.graph_root) } else { - self.r.crate_loader.process_extern_crate(item, &self.r.definitions, local_def_id).map( - |crate_id| { - self.r.extern_crate_map.insert(local_def_id, crate_id); - self.r.expect_module(crate_id.as_def_id()) - }, - ) + let crate_id = self.r.crate_loader().process_extern_crate(item, local_def_id); + crate_id.map(|crate_id| { + self.r.extern_crate_map.insert(local_def_id, crate_id); + self.r.expect_module(crate_id.as_def_id()) + }) } .map(|module| { let used = self.process_macro_use_imports(item, module); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index f6b6cf3a94c..37771693417 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -153,7 +153,7 @@ impl<'a> Resolver<'a> { if !candidates.is_empty() { show_candidates( &self.session, - &self.source_span, + &self.untracked.source_span, &mut err, span, &candidates, @@ -682,7 +682,7 @@ impl<'a> Resolver<'a> { } show_candidates( &self.session, - &self.source_span, + &self.untracked.source_span, &mut err, Some(span), &import_suggestions, @@ -1298,7 +1298,8 @@ impl<'a> Resolver<'a> { // otherwise cause duplicate suggestions. continue; } - if let Some(crate_id) = self.crate_loader.maybe_process_path_extern(ident.name) { + let crate_id = self.crate_loader().maybe_process_path_extern(ident.name); + if let Some(crate_id) = crate_id { let crate_root = self.expect_module(crate_id.as_def_id()); suggestions.extend(self.lookup_import_candidates_from_module( lookup_ident, @@ -1335,7 +1336,7 @@ impl<'a> Resolver<'a> { self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, is_expected); show_candidates( &self.session, - &self.source_span, + &self.untracked.source_span, err, None, &import_suggestions, diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 85399385d1f..b8efa3f8b27 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -107,7 +107,7 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> { r.effective_visibilities.update_eff_vis( r.local_def_id(node_id), eff_vis, - ResolverTree(&r.definitions, &r.crate_loader), + ResolverTree(&r.untracked), ) } } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index b100a8c17cf..4d896b05526 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -541,7 +541,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { if let Some(candidate) = &err.candidate { import_candidates( self.r.session, - &self.r.source_span, + &self.r.untracked.source_span, &mut diag, Some(err.span), &candidate, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index df59a350ea7..d43983ea815 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1663,8 +1663,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { if !module.no_implicit_prelude { let extern_prelude = self.r.extern_prelude.clone(); names.extend(extern_prelude.iter().flat_map(|(ident, _)| { - self.r.crate_loader.maybe_process_path_extern(ident.name).and_then( - |crate_id| { + self.r + .crate_loader() + .maybe_process_path_extern(ident.name) + .and_then(|crate_id| { let crate_mod = Res::Def(DefKind::Mod, crate_id.as_def_id()); @@ -1673,8 +1675,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } else { None } - }, - ) + }) })); if let Some(prelude) = self.r.prelude { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 4ef89cfb255..24e4b5bdd3f 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -29,7 +29,7 @@ use rustc_ast::{self as ast, NodeId, CRATE_NODE_ID}; use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, Path}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, RwLock}; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; use rustc_hir::def::Namespace::*; @@ -46,7 +46,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self, DefIdTree, MainDefinition, RegisteredTools}; use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs}; use rustc_query_system::ich::StableHashingContext; -use rustc_session::cstore::{CrateStore, MetadataLoaderDyn}; +use rustc_session::cstore::{CrateStore, MetadataLoaderDyn, Untracked}; use rustc_session::lint::LintBuffer; use rustc_session::Session; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; @@ -866,11 +866,8 @@ struct MacroData { pub struct Resolver<'a> { session: &'a Session, - definitions: Definitions, /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. expn_that_defined: FxHashMap<LocalDefId, ExpnId>, - /// Reference span for definitions. - source_span: IndexVec<LocalDefId, Span>, graph_root: Module<'a>, @@ -954,7 +951,10 @@ pub struct Resolver<'a> { arenas: &'a ResolverArenas<'a>, dummy_binding: &'a NameBinding<'a>, - crate_loader: CrateLoader<'a>, + local_crate_name: Symbol, + metadata_loader: Box<MetadataLoaderDyn>, + untracked: Untracked, + used_extern_options: FxHashSet<Symbol>, macro_names: FxHashSet<Ident>, builtin_macros: FxHashMap<Symbol, BuiltinMacroState>, /// A small map keeping true kinds of built-in macros that appear to be fn-like on @@ -1112,15 +1112,15 @@ impl<'a> AsMut<Resolver<'a>> for Resolver<'a> { /// A minimal subset of resolver that can implemenent `DefIdTree`, sometimes /// required to satisfy borrow checker by avoiding borrowing the whole resolver. #[derive(Clone, Copy)] -struct ResolverTree<'a, 'b>(&'a Definitions, &'a CrateLoader<'b>); +struct ResolverTree<'a>(&'a Untracked); -impl DefIdTree for ResolverTree<'_, '_> { +impl DefIdTree for ResolverTree<'_> { #[inline] fn opt_parent(self, id: DefId) -> Option<DefId> { - let ResolverTree(definitions, crate_loader) = self; + let ResolverTree(Untracked { definitions, cstore, .. }) = self; match id.as_local() { - Some(id) => definitions.def_key(id).parent, - None => crate_loader.cstore().def_key(id).parent, + Some(id) => definitions.read().def_key(id).parent, + None => cstore.as_any().downcast_ref::<CStore>().unwrap().def_key(id).parent, } .map(|index| DefId { index, ..id }) } @@ -1129,7 +1129,7 @@ impl DefIdTree for ResolverTree<'_, '_> { impl<'a, 'b> DefIdTree for &'a Resolver<'b> { #[inline] fn opt_parent(self, id: DefId) -> Option<DefId> { - ResolverTree(&self.definitions, &self.crate_loader).opt_parent(id) + ResolverTree(&self.untracked).opt_parent(id) } } @@ -1156,10 +1156,10 @@ impl Resolver<'_> { "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}", node_id, data, - self.definitions.def_key(self.node_id_to_def_id[&node_id]), + self.untracked.definitions.read().def_key(self.node_id_to_def_id[&node_id]), ); - let def_id = self.definitions.create_def(parent, data); + let def_id = self.untracked.definitions.write().create_def(parent, data); // Create the definition. if expn_id != ExpnId::root() { @@ -1168,7 +1168,7 @@ impl Resolver<'_> { // A relative span's parent must be an absolute span. debug_assert_eq!(span.data_untracked().parent, None); - let _id = self.source_span.push(span); + let _id = self.untracked.source_span.push(span); debug_assert_eq!(_id, def_id); // Some things for which we allocate `LocalDefId`s don't correspond to @@ -1196,7 +1196,7 @@ impl<'a> Resolver<'a> { pub fn new( session: &'a Session, krate: &Crate, - crate_name: &str, + crate_name: Symbol, metadata_loader: Box<MetadataLoaderDyn>, arenas: &'a ResolverArenas<'a>, ) -> Resolver<'a> { @@ -1258,9 +1258,7 @@ impl<'a> Resolver<'a> { let mut resolver = Resolver { session, - definitions, expn_that_defined: Default::default(), - source_span, // The outermost module has def ID 0; this is not reflected in the // AST. @@ -1311,7 +1309,14 @@ impl<'a> Resolver<'a> { vis: ty::Visibility::Public, }), - crate_loader: CrateLoader::new(session, metadata_loader, crate_name), + metadata_loader, + local_crate_name: crate_name, + used_extern_options: Default::default(), + untracked: Untracked { + cstore: Box::new(CStore::new(session)), + source_span, + definitions: RwLock::new(definitions), + }, macro_names: FxHashSet::default(), builtin_macros: Default::default(), builtin_macro_kinds: Default::default(), @@ -1402,9 +1407,6 @@ impl<'a> Resolver<'a> { pub fn into_outputs(self) -> ResolverOutputs { let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); - let definitions = self.definitions; - let cstore = Box::new(self.crate_loader.into_cstore()); - let source_span = self.source_span; let expn_that_defined = self.expn_that_defined; let visibilities = self.visibilities; let has_pub_restricted = self.has_pub_restricted; @@ -1416,9 +1418,8 @@ impl<'a> Resolver<'a> { let main_def = self.main_def; let confused_type_with_std_module = self.confused_type_with_std_module; let effective_visibilities = self.effective_visibilities; + let untracked = self.untracked; let global_ctxt = ResolverGlobalCtxt { - cstore, - source_span, expn_that_defined, visibilities, has_pub_restricted, @@ -1453,16 +1454,16 @@ impl<'a> Resolver<'a> { builtin_macro_kinds: self.builtin_macro_kinds, lifetime_elision_allowed: self.lifetime_elision_allowed, }; - ResolverOutputs { definitions, global_ctxt, ast_lowering } + ResolverOutputs { global_ctxt, ast_lowering, untracked } } pub fn clone_outputs(&self) -> ResolverOutputs { let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); - let definitions = self.definitions.clone(); + let definitions = self.untracked.definitions.clone(); let cstore = Box::new(self.cstore().clone()); + let untracked = + Untracked { cstore, source_span: self.untracked.source_span.clone(), definitions }; let global_ctxt = ResolverGlobalCtxt { - cstore, - source_span: self.source_span.clone(), expn_that_defined: self.expn_that_defined.clone(), visibilities: self.visibilities.clone(), has_pub_restricted: self.has_pub_restricted, @@ -1497,20 +1498,26 @@ impl<'a> Resolver<'a> { builtin_macro_kinds: self.builtin_macro_kinds.clone(), lifetime_elision_allowed: self.lifetime_elision_allowed.clone(), }; - ResolverOutputs { definitions, global_ctxt, ast_lowering } + ResolverOutputs { global_ctxt, ast_lowering, untracked } } fn create_stable_hashing_context(&self) -> StableHashingContext<'_> { - StableHashingContext::new( - self.session, - &self.definitions, - self.crate_loader.cstore(), - &self.source_span, + StableHashingContext::new(self.session, &self.untracked) + } + + pub fn crate_loader(&mut self) -> CrateLoader<'_> { + CrateLoader::new( + &self.session, + &*self.metadata_loader, + self.local_crate_name, + &mut *self.untracked.cstore.untracked_as_any().downcast_mut().unwrap(), + self.untracked.definitions.read(), + &mut self.used_extern_options, ) } pub fn cstore(&self) -> &CStore { - self.crate_loader.cstore() + self.untracked.cstore.as_any().downcast_ref().unwrap() } fn dummy_ext(&self, macro_kind: MacroKind) -> Lrc<SyntaxExtension> { @@ -1553,7 +1560,7 @@ impl<'a> Resolver<'a> { self.session.time("resolve_main", || self.resolve_main()); self.session.time("resolve_check_unused", || self.check_unused(krate)); self.session.time("resolve_report_errors", || self.report_errors(krate)); - self.session.time("resolve_postprocess", || self.crate_loader.postprocess(krate)); + self.session.time("resolve_postprocess", || self.crate_loader().postprocess(krate)); }); } @@ -1871,10 +1878,10 @@ impl<'a> Resolver<'a> { } else { let crate_id = if finalize { let Some(crate_id) = - self.crate_loader.process_path_extern(ident.name, ident.span) else { return Some(self.dummy_binding); }; + self.crate_loader().process_path_extern(ident.name, ident.span) else { return Some(self.dummy_binding); }; crate_id } else { - self.crate_loader.maybe_process_path_extern(ident.name)? + self.crate_loader().maybe_process_path_extern(ident.name)? }; let crate_root = self.expect_module(crate_id.as_def_id()); let vis = ty::Visibility::<LocalDefId>::Public; @@ -1946,14 +1953,14 @@ impl<'a> Resolver<'a> { /// Retrieves the span of the given `DefId` if `DefId` is in the local crate. #[inline] pub fn opt_span(&self, def_id: DefId) -> Option<Span> { - def_id.as_local().map(|def_id| self.source_span[def_id]) + def_id.as_local().map(|def_id| self.untracked.source_span[def_id]) } /// Retrieves the name of the given `DefId`. #[inline] pub fn opt_name(&self, def_id: DefId) -> Option<Symbol> { let def_key = match def_id.as_local() { - Some(def_id) => self.definitions.def_key(def_id), + Some(def_id) => self.untracked.definitions.read().def_key(def_id), None => self.cstore().def_key(def_id), }; def_key.get_opt_name() diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 8c7972f8eeb..b5b1602c5e0 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -455,7 +455,7 @@ impl<'a> ResolverExpand for Resolver<'a> { } fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span { - self.crate_loader.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.session) + self.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.session) } fn declare_proc_macro(&mut self, id: NodeId) { diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index b4528853825..9ae07cb005b 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -111,7 +111,7 @@ impl<'tcx> DumpVisitor<'tcx> { self.save_ctxt.lookup_def_id(ref_id) } - pub fn dump_crate_info(&mut self, name: &str) { + pub fn dump_crate_info(&mut self, name: Symbol) { let source_file = self.tcx.sess.local_crate_source_file.as_ref(); let crate_root = source_file.map(|source_file| { let source_file = Path::new(source_file); @@ -124,7 +124,7 @@ impl<'tcx> DumpVisitor<'tcx> { let data = CratePreludeData { crate_id: GlobalCrateId { - name: name.into(), + name: name.to_string(), disambiguator: (self.tcx.sess.local_stable_crate_id().to_u64(), 0), }, crate_root: crate_root.unwrap_or_else(|| "<no source>".to_owned()), @@ -135,7 +135,7 @@ impl<'tcx> DumpVisitor<'tcx> { self.dumper.crate_prelude(data); } - pub fn dump_compilation_options(&mut self, input: &Input, crate_name: &str) { + pub fn dump_compilation_options(&mut self, input: &Input, crate_name: Symbol) { // Apply possible `remap-path-prefix` remapping to the input source file // (and don't include remapping args anymore) let (program, arguments) = { diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index f05eb2b7432..7735c571310 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -95,7 +95,7 @@ impl<'tcx> SaveContext<'tcx> { } /// Returns path to the compilation output (e.g., libfoo-12345678.rmeta) - pub fn compilation_output(&self, crate_name: &str) -> PathBuf { + pub fn compilation_output(&self, crate_name: Symbol) -> PathBuf { let sess = &self.tcx.sess; // Save-analysis is emitted per whole session, not per each crate type let crate_type = sess.crate_types()[0]; @@ -894,8 +894,8 @@ pub struct DumpHandler<'a> { } impl<'a> DumpHandler<'a> { - pub fn new(odir: Option<&'a Path>, cratename: &str) -> DumpHandler<'a> { - DumpHandler { odir, cratename: cratename.to_owned() } + pub fn new(odir: Option<&'a Path>, cratename: Symbol) -> DumpHandler<'a> { + DumpHandler { odir, cratename: cratename.to_string() } } fn output_file(&self, ctx: &SaveContext<'_>) -> (BufWriter<File>, PathBuf) { @@ -960,7 +960,7 @@ impl SaveHandler for CallbackHandler<'_> { pub fn process_crate<'l, 'tcx, H: SaveHandler>( tcx: TyCtxt<'tcx>, - cratename: &str, + cratename: Symbol, input: &'l Input, config: Option<Config>, mut handler: H, diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index a052f293341..d8db86c5f62 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -13,11 +13,13 @@ rustc_hir = { path = "../rustc_hir" } rustc_target = { path = "../rustc_target" } rustc_serialize = { path = "../rustc_serialize" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_index = { path = "../rustc_index" } rustc_span = { path = "../rustc_span" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_ast = { path = "../rustc_ast" } rustc_lint_defs = { path = "../rustc_lint_defs" } smallvec = "1.8.1" +termize = "0.1.1" [target.'cfg(unix)'.dependencies] libc = "0.2" diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs index eede4d16ea3..1085bce4475 100644 --- a/compiler/rustc_session/src/code_stats.rs +++ b/compiler/rustc_session/src/code_stats.rs @@ -19,7 +19,7 @@ pub enum SizeKind { Min, } -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct FieldInfo { pub name: Symbol, pub offset: u64, @@ -33,6 +33,7 @@ pub enum DataTypeKind { Union, Enum, Closure, + Generator, } #[derive(PartialEq, Eq, Hash, Debug)] @@ -114,7 +115,7 @@ impl CodeStats { let struct_like = match kind { DataTypeKind::Struct | DataTypeKind::Closure => true, - DataTypeKind::Enum | DataTypeKind::Union => false, + DataTypeKind::Enum | DataTypeKind::Union | DataTypeKind::Generator => false, }; for (i, variant_info) in variants.into_iter().enumerate() { let VariantInfo { ref name, kind: _, align: _, size, ref fields } = *variant_info; diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 7d4a1e212a4..7f926f7d8bc 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -6,9 +6,10 @@ use crate::search_paths::PathKind; use crate::utils::NativeLibKind; use crate::Session; use rustc_ast as ast; -use rustc_data_structures::sync::{self, MetadataRef}; -use rustc_hir::def_id::{CrateNum, DefId, StableCrateId, LOCAL_CRATE}; -use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; +use rustc_data_structures::sync::{self, MetadataRef, RwLock}; +use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE}; +use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; +use rustc_index::vec::IndexVec; use rustc_span::hygiene::{ExpnHash, ExpnId}; use rustc_span::symbol::Symbol; use rustc_span::Span; @@ -217,6 +218,7 @@ pub type MetadataLoaderDyn = dyn MetadataLoader + Sync; /// during resolve) pub trait CrateStore: std::fmt::Debug { fn as_any(&self) -> &dyn Any; + fn untracked_as_any(&mut self) -> &mut dyn Any; // Foreign definitions. // This information is safe to access, since it's hashed as part of the DefPathHash, which incr. @@ -249,3 +251,11 @@ pub trait CrateStore: std::fmt::Debug { } pub type CrateStoreDyn = dyn CrateStore + sync::Sync; + +#[derive(Debug)] +pub struct Untracked { + pub cstore: Box<CrateStoreDyn>, + /// Reference span for definitions. + pub source_span: IndexVec<LocalDefId, Span>, + pub definitions: RwLock<Definitions>, +} diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 8cb9e1a6f1a..ee492f802a7 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -129,10 +129,10 @@ pub struct FileIsNotWriteable<'a> { #[derive(Diagnostic)] #[diag(session_crate_name_does_not_match)] -pub struct CrateNameDoesNotMatch<'a> { +pub struct CrateNameDoesNotMatch { #[primary_span] pub span: Span, - pub s: &'a str, + pub s: Symbol, pub name: Symbol, } @@ -151,11 +151,11 @@ pub struct CrateNameEmpty { #[derive(Diagnostic)] #[diag(session_invalid_character_in_create_name)] -pub struct InvalidCharacterInCrateName<'a> { +pub struct InvalidCharacterInCrateName { #[primary_span] pub span: Option<Span>, pub character: char, - pub crate_name: &'a str, + pub crate_name: Symbol, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 8e9198b79df..dab9c736d14 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -368,7 +368,7 @@ mod desc { pub const parse_opt_panic_strategy: &str = parse_panic_strategy; pub const parse_oom_strategy: &str = "either `panic` or `abort`"; pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; - pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `leak`, `memory`, `memtag`, `shadow-call-stack`, or `thread`"; + pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `kcfi`, `leak`, `memory`, `memtag`, `shadow-call-stack`, or `thread`"; pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2"; pub const parse_cfguard: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; @@ -675,6 +675,7 @@ mod parse { *slot |= match s { "address" => SanitizerSet::ADDRESS, "cfi" => SanitizerSet::CFI, + "kcfi" => SanitizerSet::KCFI, "leak" => SanitizerSet::LEAK, "memory" => SanitizerSet::MEMORY, "memtag" => SanitizerSet::MEMTAG, diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index 2511bee46af..8ee3057de62 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -7,14 +7,14 @@ use crate::errors::{ use crate::Session; use rustc_ast as ast; use rustc_span::symbol::sym; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use std::path::{Path, PathBuf}; pub fn out_filename( sess: &Session, crate_type: CrateType, outputs: &OutputFilenames, - crate_name: &str, + crate_name: Symbol, ) -> PathBuf { let default_filename = filename_for_input(sess, crate_type, crate_name, outputs); let out_filename = outputs @@ -45,9 +45,9 @@ fn is_writeable(p: &Path) -> bool { } } -pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) -> String { - let validate = |s: String, span: Option<Span>| { - validate_crate_name(sess, &s, span); +pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) -> Symbol { + let validate = |s: Symbol, span: Option<Span>| { + validate_crate_name(sess, s, span); s }; @@ -59,38 +59,39 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) sess.find_by_name(attrs, sym::crate_name).and_then(|at| at.value_str().map(|s| (at, s))); if let Some(ref s) = sess.opts.crate_name { + let s = Symbol::intern(s); if let Some((attr, name)) = attr_crate_name { - if name.as_str() != s { + if name != s { sess.emit_err(CrateNameDoesNotMatch { span: attr.span, s, name }); } } - return validate(s.clone(), None); + return validate(s, None); } if let Some((attr, s)) = attr_crate_name { - return validate(s.to_string(), Some(attr.span)); + return validate(s, Some(attr.span)); } if let Input::File(ref path) = *input { if let Some(s) = path.file_stem().and_then(|s| s.to_str()) { if s.starts_with('-') { sess.emit_err(CrateNameInvalid { s }); } else { - return validate(s.replace('-', "_"), None); + return validate(Symbol::intern(&s.replace('-', "_")), None); } } } - "rust_out".to_string() + Symbol::intern("rust_out") } -pub fn validate_crate_name(sess: &Session, s: &str, sp: Option<Span>) { +pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) { let mut err_count = 0; { if s.is_empty() { err_count += 1; sess.emit_err(CrateNameEmpty { span: sp }); } - for c in s.chars() { + for c in s.as_str().chars() { if c.is_alphanumeric() { continue; } @@ -109,7 +110,7 @@ pub fn validate_crate_name(sess: &Session, s: &str, sp: Option<Span>) { pub fn filename_for_metadata( sess: &Session, - crate_name: &str, + crate_name: Symbol, outputs: &OutputFilenames, ) -> PathBuf { // If the command-line specified the path, use that directly. @@ -132,7 +133,7 @@ pub fn filename_for_metadata( pub fn filename_for_input( sess: &Session, crate_type: CrateType, - crate_name: &str, + crate_name: Symbol, outputs: &OutputFilenames, ) -> PathBuf { let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index e99e460913e..8859b76d289 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -686,6 +686,10 @@ impl Session { self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI) } + pub fn is_sanitizer_kcfi_enabled(&self) -> bool { + self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI) + } + /// Check whether this compile session and crate type use static crt. pub fn crt_static(&self, crate_type: Option<CrateType>) -> bool { if !self.target.crt_static_respected { @@ -952,6 +956,17 @@ impl Session { ) -> Option<Symbol> { attrs.iter().find(|at| at.has_name(name)).and_then(|at| at.value_str()) } + + pub fn diagnostic_width(&self) -> usize { + let default_column_width = 140; + if let Some(width) = self.opts.diagnostic_width { + width + } else if self.opts.unstable_opts.ui_testing { + default_column_width + } else { + termize::dimensions().map_or(default_column_width, |(w, _)| w) + } + } } // JUSTIFICATION: defn of the suggested wrapper fns @@ -1533,6 +1548,14 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } + // LLVM CFI and KCFI are mutually exclusive + if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() { + sess.emit_err(CannotMixAndMatchSanitizers { + first: "cfi".to_string(), + second: "kcfi".to_string(), + }); + } + if sess.opts.unstable_opts.stack_protector != StackProtector::None { if !sess.target.options.supports_stack_protector { sess.emit_warning(StackProtectorNotSupportedForTarget { diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 0ad1f1a0da7..e62ce2c266a 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -1,4 +1,4 @@ -use crate::HashStableContext; +use crate::{HashStableContext, Symbol}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_data_structures::AtomicRef; @@ -149,9 +149,11 @@ impl StableCrateId { /// Computes the stable ID for a crate with the given name and /// `-Cmetadata` arguments. - pub fn new(crate_name: &str, is_exe: bool, mut metadata: Vec<String>) -> StableCrateId { + pub fn new(crate_name: Symbol, is_exe: bool, mut metadata: Vec<String>) -> StableCrateId { let mut hasher = StableHasher::new(); - crate_name.hash(&mut hasher); + // We must hash the string text of the crate name, not the id, as the id is not stable + // across builds. + crate_name.as_str().hash(&mut hasher); // We don't want the stable crate ID to depend on the order of // -C metadata arguments, so sort them: diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index cef4c6f79ce..335bfc3302f 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -491,6 +491,10 @@ impl SpanData { pub fn is_dummy(self) -> bool { self.lo.0 == 0 && self.hi.0 == 0 } + #[inline] + pub fn is_visible(self, sm: &SourceMap) -> bool { + !self.is_dummy() && sm.is_span_accessible(self.span()) + } /// Returns `true` if `self` fully encloses `other`. pub fn contains(self, other: Self) -> bool { self.lo <= other.lo && other.hi <= self.hi @@ -556,6 +560,11 @@ impl Span { self.data_untracked().is_dummy() } + #[inline] + pub fn is_visible(self, sm: &SourceMap) -> bool { + self.data_untracked().is_visible(sm) + } + /// Returns `true` if this span comes from any kind of macro, desugaring or inlining. #[inline] pub fn from_expansion(self) -> bool { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 61253845497..1fcf8c7a8bf 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -828,6 +828,7 @@ symbols! { item_like_imports, iter, iter_repeat, + kcfi, keyword, kind, kreg, diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index 2a29ad6a9e5..4e447eab02e 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -10,6 +10,7 @@ bitflags = "1.2.1" tracing = "0.1" punycode = "0.4.0" rustc-demangle = "0.1.21" +twox-hash = "1.6.3" rustc_span = { path = "../rustc_span" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs index 9228bea43f9..53983bed718 100644 --- a/compiler/rustc_symbol_mangling/src/typeid.rs +++ b/compiler/rustc_symbol_mangling/src/typeid.rs @@ -3,6 +3,8 @@ use rustc_middle::ty::{FnSig, Ty, TyCtxt}; use rustc_target::abi::call::FnAbi; +use std::hash::Hasher; +use twox_hash::XxHash64; mod typeid_itanium_cxx_abi; use typeid_itanium_cxx_abi::TypeIdOptions; @@ -16,3 +18,25 @@ pub fn typeid_for_fnabi<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) pub fn typeid_for_fnsig<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: &FnSig<'tcx>) -> String { typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, TypeIdOptions::NO_OPTIONS) } + +/// Returns an LLVM KCFI type metadata identifier for the specified FnAbi. +pub fn kcfi_typeid_for_fnabi<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> u32 { + // An LLVM KCFI type metadata identifier is a 32-bit constant produced by taking the lower half + // of the xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) + let mut hash: XxHash64 = Default::default(); + hash.write( + typeid_itanium_cxx_abi::typeid_for_fnabi(tcx, fn_abi, TypeIdOptions::NO_OPTIONS).as_bytes(), + ); + hash.finish() as u32 +} + +/// Returns an LLVM KCFI type metadata identifier for the specified FnSig. +pub fn kcfi_typeid_for_fnsig<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: &FnSig<'tcx>) -> u32 { + // An LLVM KCFI type metadata identifier is a 32-bit constant produced by taking the lower half + // of the xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) + let mut hash: XxHash64 = Default::default(); + hash.write( + typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, TypeIdOptions::NO_OPTIONS).as_bytes(), + ); + hash.finish() as u32 +} diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs index 4ae6d4120c9..aca52e1478e 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs @@ -6,13 +6,16 @@ // // For example, `-C target-cpu=cortex-a53`. -use super::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; +use super::{ + Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, TargetOptions, +}; pub fn target() -> Target { let opts = TargetOptions { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), features: "+strict-align,+neon,+fp-armv8".into(), + supported_sanitizers: SanitizerSet::KCFI, relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 7f8160b5dec..fc6a2edabb7 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -204,7 +204,7 @@ pub fn macos_llvm_target(arch: Arch) -> String { fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]> { // Apple platforms only officially support macOS as a host for any compilation. // - // If building for macOS, we go ahead and remove any erronous environment state + // If building for macOS, we go ahead and remove any erroneous environment state // that's only applicable to cross-OS compilation. Always leave anything for the // host OS alone though. if os == "macos" { diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index d05b8aa4200..1db1d7e85ad 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -804,7 +804,7 @@ impl ToJson for StackProbeType { bitflags::bitflags! { #[derive(Default, Encodable, Decodable)] - pub struct SanitizerSet: u8 { + pub struct SanitizerSet: u16 { const ADDRESS = 1 << 0; const LEAK = 1 << 1; const MEMORY = 1 << 2; @@ -813,6 +813,7 @@ bitflags::bitflags! { const CFI = 1 << 5; const MEMTAG = 1 << 6; const SHADOWCALLSTACK = 1 << 7; + const KCFI = 1 << 8; } } @@ -824,6 +825,7 @@ impl SanitizerSet { Some(match self { SanitizerSet::ADDRESS => "address", SanitizerSet::CFI => "cfi", + SanitizerSet::KCFI => "kcfi", SanitizerSet::LEAK => "leak", SanitizerSet::MEMORY => "memory", SanitizerSet::MEMTAG => "memtag", @@ -859,6 +861,7 @@ impl IntoIterator for SanitizerSet { [ SanitizerSet::ADDRESS, SanitizerSet::CFI, + SanitizerSet::KCFI, SanitizerSet::LEAK, SanitizerSet::MEMORY, SanitizerSet::MEMTAG, @@ -2327,6 +2330,7 @@ impl Target { base.$key_name |= match s.as_str() { Some("address") => SanitizerSet::ADDRESS, Some("cfi") => SanitizerSet::CFI, + Some("kcfi") => SanitizerSet::KCFI, Some("leak") => SanitizerSet::LEAK, Some("memory") => SanitizerSet::MEMORY, Some("memtag") => SanitizerSet::MEMTAG, diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs index 8dad941b534..06529c2e403 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs @@ -33,12 +33,6 @@ pub fn target() -> Target { // For now this target just never has an entry symbol no matter the output // type, so unconditionally pass this. "--no-entry", - // Rust really needs a way for users to specify exports and imports in - // the source code. --export-dynamic isn't the right tool for this job, - // however it does have the side effect of automatically exporting a lot - // of symbols, which approximates what people want when compiling for - // wasm32-unknown-unknown expect, so use it for now. - "--export-dynamic", ], ); options.add_pre_link_args( @@ -48,7 +42,6 @@ pub fn target() -> Target { // otherwise "--target=wasm32-unknown-unknown", "-Wl,--no-entry", - "-Wl,--export-dynamic", ], ); diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 6f0bbf0672d..a0476d542e6 100644 --- a/compiler/rustc_target/src/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs @@ -104,6 +104,10 @@ pub fn target() -> Target { // `args::args()` makes the WASI API calls itself. options.main_needs_argc_argv = false; + // And, WASI mangles the name of "main" to distinguish between different + // signatures. + options.entry_name = "__main_void".into(); + Target { llvm_target: "wasm32-wasi".into(), pointer_width: 32, diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs index e4d33c2b8c6..32060c35c11 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs @@ -5,7 +5,7 @@ // features. use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy}; -use super::{RelroLevel, StackProbeType, Target, TargetOptions}; +use super::{RelroLevel, SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let opts = TargetOptions { @@ -20,6 +20,7 @@ pub fn target() -> Target { features: "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float" .into(), + supported_sanitizers: SanitizerSet::KCFI, disable_redzone: true, panic_strategy: PanicStrategy::Abort, code_model: Some(CodeModel::Kernel), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 6ea54b625bb..443d57aaf3d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2413,19 +2413,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => { let item_name = tcx.def_path_str(item_def_id); let mut multispan = MultiSpan::from(span); + let sm = tcx.sess.source_map(); if let Some(ident) = tcx.opt_item_ident(item_def_id) { - let sm = tcx.sess.source_map(); let same_line = match (sm.lookup_line(ident.span.hi()), sm.lookup_line(span.lo())) { (Ok(l), Ok(r)) => l.line == r.line, _ => true, }; - if !ident.span.is_dummy() && !ident.span.overlaps(span) && !same_line { + if ident.span.is_visible(sm) && !ident.span.overlaps(span) && !same_line { multispan.push_span_label(ident.span, "required by a bound in this"); } } let descr = format!("required by a bound in `{}`", item_name); - if !span.is_dummy() { + if span.is_visible(sm) { let msg = format!("required by this bound in `{}`", item_name); multispan.push_span_label(span, msg); err.span_note(multispan, &descr); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index d3cfd61e195..ea4bf42c515 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -4,7 +4,6 @@ pub mod auto_trait; mod chalk_fulfill; -pub mod codegen; mod coherence; pub mod const_evaluatable; mod engine; @@ -20,9 +19,9 @@ mod select; mod specialize; mod structural_match; mod util; +mod vtable; pub mod wf; -use crate::errors::DumpVTableEntries; use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::traits::error_reporting::TypeErrCtxtExt as _; @@ -30,15 +29,11 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_hir::lang_items::LangItem; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{ - self, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeSuperVisitable, VtblEntry, -}; +use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeSuperVisitable}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; -use rustc_span::{sym, Span}; -use smallvec::SmallVec; +use rustc_span::Span; use std::fmt::Debug; use std::ops::ControlFlow; @@ -567,369 +562,12 @@ fn is_impossible_method<'tcx>( false } -#[derive(Clone, Debug)] -enum VtblSegment<'tcx> { - MetadataDSA, - TraitOwnEntries { trait_ref: ty::PolyTraitRef<'tcx>, emit_vptr: bool }, -} - -/// Prepare the segments for a vtable -fn prepare_vtable_segments<'tcx, T>( - tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, - mut segment_visitor: impl FnMut(VtblSegment<'tcx>) -> ControlFlow<T>, -) -> Option<T> { - // The following constraints holds for the final arrangement. - // 1. The whole virtual table of the first direct super trait is included as the - // the prefix. If this trait doesn't have any super traits, then this step - // consists of the dsa metadata. - // 2. Then comes the proper pointer metadata(vptr) and all own methods for all - // other super traits except those already included as part of the first - // direct super trait virtual table. - // 3. finally, the own methods of this trait. - - // This has the advantage that trait upcasting to the first direct super trait on each level - // is zero cost, and to another trait includes only replacing the pointer with one level indirection, - // while not using too much extra memory. - - // For a single inheritance relationship like this, - // D --> C --> B --> A - // The resulting vtable will consists of these segments: - // DSA, A, B, C, D - - // For a multiple inheritance relationship like this, - // D --> C --> A - // \-> B - // The resulting vtable will consists of these segments: - // DSA, A, B, B-vptr, C, D - - // For a diamond inheritance relationship like this, - // D --> B --> A - // \-> C -/ - // The resulting vtable will consists of these segments: - // DSA, A, B, C, C-vptr, D - - // For a more complex inheritance relationship like this: - // O --> G --> C --> A - // \ \ \-> B - // | |-> F --> D - // | \-> E - // |-> N --> J --> H - // \ \-> I - // |-> M --> K - // \-> L - // The resulting vtable will consists of these segments: - // DSA, A, B, B-vptr, C, D, D-vptr, E, E-vptr, F, F-vptr, G, - // H, H-vptr, I, I-vptr, J, J-vptr, K, K-vptr, L, L-vptr, M, M-vptr, - // N, N-vptr, O - - // emit dsa segment first. - if let ControlFlow::Break(v) = (segment_visitor)(VtblSegment::MetadataDSA) { - return Some(v); - } - - let mut emit_vptr_on_new_entry = false; - let mut visited = util::PredicateSet::new(tcx); - let predicate = trait_ref.without_const().to_predicate(tcx); - let mut stack: SmallVec<[(ty::PolyTraitRef<'tcx>, _, _); 5]> = - smallvec![(trait_ref, emit_vptr_on_new_entry, None)]; - visited.insert(predicate); - - // the main traversal loop: - // basically we want to cut the inheritance directed graph into a few non-overlapping slices of nodes - // that each node is emitted after all its descendents have been emitted. - // so we convert the directed graph into a tree by skipping all previously visited nodes using a visited set. - // this is done on the fly. - // Each loop run emits a slice - it starts by find a "childless" unvisited node, backtracking upwards, and it - // stops after it finds a node that has a next-sibling node. - // This next-sibling node will used as the starting point of next slice. - - // Example: - // For a diamond inheritance relationship like this, - // D#1 --> B#0 --> A#0 - // \-> C#1 -/ - - // Starting point 0 stack [D] - // Loop run #0: Stack after diving in is [D B A], A is "childless" - // after this point, all newly visited nodes won't have a vtable that equals to a prefix of this one. - // Loop run #0: Emitting the slice [B A] (in reverse order), B has a next-sibling node, so this slice stops here. - // Loop run #0: Stack after exiting out is [D C], C is the next starting point. - // Loop run #1: Stack after diving in is [D C], C is "childless", since its child A is skipped(already emitted). - // Loop run #1: Emitting the slice [D C] (in reverse order). No one has a next-sibling node. - // Loop run #1: Stack after exiting out is []. Now the function exits. - - loop { - // dive deeper into the stack, recording the path - 'diving_in: loop { - if let Some((inner_most_trait_ref, _, _)) = stack.last() { - let inner_most_trait_ref = *inner_most_trait_ref; - let mut direct_super_traits_iter = tcx - .super_predicates_of(inner_most_trait_ref.def_id()) - .predicates - .into_iter() - .filter_map(move |(pred, _)| { - pred.subst_supertrait(tcx, &inner_most_trait_ref).to_opt_poly_trait_pred() - }); - - 'diving_in_skip_visited_traits: loop { - if let Some(next_super_trait) = direct_super_traits_iter.next() { - if visited.insert(next_super_trait.to_predicate(tcx)) { - // We're throwing away potential constness of super traits here. - // FIXME: handle ~const super traits - let next_super_trait = next_super_trait.map_bound(|t| t.trait_ref); - stack.push(( - next_super_trait, - emit_vptr_on_new_entry, - Some(direct_super_traits_iter), - )); - break 'diving_in_skip_visited_traits; - } else { - continue 'diving_in_skip_visited_traits; - } - } else { - break 'diving_in; - } - } - } - } - - // Other than the left-most path, vptr should be emitted for each trait. - emit_vptr_on_new_entry = true; - - // emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level. - 'exiting_out: loop { - if let Some((inner_most_trait_ref, emit_vptr, siblings_opt)) = stack.last_mut() { - if let ControlFlow::Break(v) = (segment_visitor)(VtblSegment::TraitOwnEntries { - trait_ref: *inner_most_trait_ref, - emit_vptr: *emit_vptr, - }) { - return Some(v); - } - - 'exiting_out_skip_visited_traits: loop { - if let Some(siblings) = siblings_opt { - if let Some(next_inner_most_trait_ref) = siblings.next() { - if visited.insert(next_inner_most_trait_ref.to_predicate(tcx)) { - // We're throwing away potential constness of super traits here. - // FIXME: handle ~const super traits - let next_inner_most_trait_ref = - next_inner_most_trait_ref.map_bound(|t| t.trait_ref); - *inner_most_trait_ref = next_inner_most_trait_ref; - *emit_vptr = emit_vptr_on_new_entry; - break 'exiting_out; - } else { - continue 'exiting_out_skip_visited_traits; - } - } - } - stack.pop(); - continue 'exiting_out; - } - } - // all done - return None; - } - } -} - -fn dump_vtable_entries<'tcx>( - tcx: TyCtxt<'tcx>, - sp: Span, - trait_ref: ty::PolyTraitRef<'tcx>, - entries: &[VtblEntry<'tcx>], -) { - tcx.sess.emit_err(DumpVTableEntries { - span: sp, - trait_ref, - entries: format!("{:#?}", entries), - }); -} - -fn own_existential_vtable_entries<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> &'tcx [DefId] { - let trait_methods = tcx - .associated_items(trait_def_id) - .in_definition_order() - .filter(|item| item.kind == ty::AssocKind::Fn); - // Now list each method's DefId (for within its trait). - let own_entries = trait_methods.filter_map(move |trait_method| { - debug!("own_existential_vtable_entry: trait_method={:?}", trait_method); - let def_id = trait_method.def_id; - - // Some methods cannot be called on an object; skip those. - if !is_vtable_safe_method(tcx, trait_def_id, &trait_method) { - debug!("own_existential_vtable_entry: not vtable safe"); - return None; - } - - Some(def_id) - }); - - tcx.arena.alloc_from_iter(own_entries.into_iter()) -} - -/// Given a trait `trait_ref`, iterates the vtable entries -/// that come from `trait_ref`, including its supertraits. -fn vtable_entries<'tcx>( - tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, -) -> &'tcx [VtblEntry<'tcx>] { - debug!("vtable_entries({:?})", trait_ref); - - let mut entries = vec![]; - - let vtable_segment_callback = |segment| -> ControlFlow<()> { - match segment { - VtblSegment::MetadataDSA => { - entries.extend(TyCtxt::COMMON_VTABLE_ENTRIES); - } - VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { - let existential_trait_ref = trait_ref - .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); - - // Lookup the shape of vtable for the trait. - let own_existential_entries = - tcx.own_existential_vtable_entries(existential_trait_ref.def_id()); - - let own_entries = own_existential_entries.iter().copied().map(|def_id| { - debug!("vtable_entries: trait_method={:?}", def_id); - - // The method may have some early-bound lifetimes; add regions for those. - let substs = trait_ref.map_bound(|trait_ref| { - InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind { - GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } - | GenericParamDefKind::Const { .. } => { - trait_ref.substs[param.index as usize] - } - }) - }); - - // The trait type may have higher-ranked lifetimes in it; - // erase them if they appear, so that we get the type - // at some particular call site. - let substs = tcx - .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), substs); - - // It's possible that the method relies on where-clauses that - // do not hold for this particular set of type parameters. - // Note that this method could then never be called, so we - // do not want to try and codegen it, in that case (see #23435). - let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); - if impossible_predicates(tcx, predicates.predicates) { - debug!("vtable_entries: predicates do not hold"); - return VtblEntry::Vacant; - } - - let instance = ty::Instance::resolve_for_vtable( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - substs, - ) - .expect("resolution failed during building vtable representation"); - VtblEntry::Method(instance) - }); - - entries.extend(own_entries); - - if emit_vptr { - entries.push(VtblEntry::TraitVPtr(trait_ref)); - } - } - } - - ControlFlow::Continue(()) - }; - - let _ = prepare_vtable_segments(tcx, trait_ref, vtable_segment_callback); - - if tcx.has_attr(trait_ref.def_id(), sym::rustc_dump_vtable) { - let sp = tcx.def_span(trait_ref.def_id()); - dump_vtable_entries(tcx, sp, trait_ref, &entries); - } - - tcx.arena.alloc_from_iter(entries.into_iter()) -} - -/// Find slot base for trait methods within vtable entries of another trait -fn vtable_trait_first_method_offset<'tcx>( - tcx: TyCtxt<'tcx>, - key: ( - ty::PolyTraitRef<'tcx>, // trait_to_be_found - ty::PolyTraitRef<'tcx>, // trait_owning_vtable - ), -) -> usize { - let (trait_to_be_found, trait_owning_vtable) = key; - - // #90177 - let trait_to_be_found_erased = tcx.erase_regions(trait_to_be_found); - - let vtable_segment_callback = { - let mut vtable_base = 0; - - move |segment| { - match segment { - VtblSegment::MetadataDSA => { - vtable_base += TyCtxt::COMMON_VTABLE_ENTRIES.len(); - } - VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { - if tcx.erase_regions(trait_ref) == trait_to_be_found_erased { - return ControlFlow::Break(vtable_base); - } - vtable_base += util::count_own_vtable_entries(tcx, trait_ref); - if emit_vptr { - vtable_base += 1; - } - } - } - ControlFlow::Continue(()) - } - }; - - if let Some(vtable_base) = - prepare_vtable_segments(tcx, trait_owning_vtable, vtable_segment_callback) - { - vtable_base - } else { - bug!("Failed to find info for expected trait in vtable"); - } -} - -/// Find slot offset for trait vptr within vtable entries of another trait -pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( - tcx: TyCtxt<'tcx>, - key: ( - Ty<'tcx>, // trait object type whose trait owning vtable - Ty<'tcx>, // trait object for supertrait - ), -) -> Option<usize> { - let (source, target) = key; - assert!(matches!(&source.kind(), &ty::Dynamic(..)) && !source.needs_infer()); - assert!(matches!(&target.kind(), &ty::Dynamic(..)) && !target.needs_infer()); - - // this has been typecked-before, so diagnostics is not really needed. - let unsize_trait_did = tcx.require_lang_item(LangItem::Unsize, None); - - let trait_ref = tcx.mk_trait_ref(unsize_trait_did, [source, target]); - - match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) { - Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => { - implsrc_traitcasting.vtable_vptr_slot - } - otherwise => bug!("expected TraitUpcasting candidate, got {otherwise:?}"), - } -} - pub fn provide(providers: &mut ty::query::Providers) { object_safety::provide(providers); - structural_match::provide(providers); + vtable::provide(providers); *providers = ty::query::Providers { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, - codegen_select_candidate: codegen::codegen_select_candidate, - own_existential_vtable_entries, - vtable_entries, - vtable_trait_upcasting_coercion_new_vptr_slot, subst_and_check_impossible_predicates, is_impossible_method, ..*providers diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 22cd700dcb5..fda415155c4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -19,6 +19,10 @@ use rustc_span::def_id::DefId; use crate::traits::project::{normalize_with_depth, normalize_with_depth_to}; use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for_trait_def}; +use crate::traits::vtable::{ + count_own_vtable_entries, prepare_vtable_segments, vtable_trait_first_method_offset, + VtblSegment, +}; use crate::traits::{ BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource, ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData, @@ -26,7 +30,7 @@ use crate::traits::{ ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation, Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, - SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment, + SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, }; use super::BuiltinImplConditions; @@ -583,7 +587,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?nested, "object nested obligations"); - let vtable_base = super::super::vtable_trait_first_method_offset( + let vtable_base = vtable_trait_first_method_offset( tcx, (unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)), ); @@ -904,7 +908,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len(); } VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { - vptr_offset += util::count_own_vtable_entries(tcx, trait_ref); + vptr_offset += count_own_vtable_entries(tcx, trait_ref); if trait_ref == upcast_trait_ref { if emit_vptr { return ControlFlow::Break(Some(vptr_offset)); @@ -923,8 +927,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }; let vtable_vptr_slot = - super::super::prepare_vtable_segments(tcx, source_trait_ref, vtable_segment_callback) - .unwrap(); + prepare_vtable_segments(tcx, source_trait_ref, vtable_segment_callback).unwrap(); Ok(ImplSourceTraitUpcastingData { upcast_trait_ref, vtable_vptr_slot, nested }) } diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 40dbe0b3ff0..4dc08e0f9da 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -1,10 +1,5 @@ -use crate::infer::{InferCtxt, TyCtxtInferExt}; -use crate::traits::{ObligationCause, ObligationCtxt}; - use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_hir::lang_items::LangItem; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_span::Span; use std::ops::ControlFlow; @@ -59,41 +54,6 @@ pub fn search_for_adt_const_param_violation<'tcx>( .break_value() } -/// This method returns true if and only if `adt_ty` itself has been marked as -/// eligible for structural-match: namely, if it implements both -/// `StructuralPartialEq` and `StructuralEq` (which are respectively injected by -/// `#[derive(PartialEq)]` and `#[derive(Eq)]`). -/// -/// Note that this does *not* recursively check if the substructure of `adt_ty` -/// implements the traits. -fn type_marked_structural<'tcx>( - infcx: &InferCtxt<'tcx>, - adt_ty: Ty<'tcx>, - cause: ObligationCause<'tcx>, -) -> bool { - let ocx = ObligationCtxt::new(infcx); - // require `#[derive(PartialEq)]` - let structural_peq_def_id = - infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span)); - ocx.register_bound(cause.clone(), ty::ParamEnv::empty(), adt_ty, structural_peq_def_id); - // for now, require `#[derive(Eq)]`. (Doing so is a hack to work around - // the type `for<'a> fn(&'a ())` failing to implement `Eq` itself.) - let structural_teq_def_id = - infcx.tcx.require_lang_item(LangItem::StructuralTeq, Some(cause.span)); - ocx.register_bound(cause, ty::ParamEnv::empty(), adt_ty, structural_teq_def_id); - - // We deliberately skip *reporting* fulfillment errors (via - // `report_fulfillment_errors`), for two reasons: - // - // 1. The error messages would mention `std::marker::StructuralPartialEq` - // (a trait which is solely meant as an implementation detail - // for now), and - // - // 2. We are sometimes doing future-incompatibility lints for - // now, so we do not want unconditional errors here. - ocx.select_all_or_error().is_empty() -} - /// This implements the traversal over the structure of a given type to try to /// find instances of ADTs (specifically structs or enums) that do not implement /// the structural-match traits (`StructuralPartialEq` and `StructuralEq`). @@ -249,11 +209,3 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { }) } } - -pub fn provide(providers: &mut Providers) { - providers.has_structural_eq_impls = |tcx, ty| { - let infcx = tcx.infer_ctxt().build(); - let cause = ObligationCause::dummy(); - type_marked_structural(&infcx, ty, cause) - }; -} diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 51968c2d7a1..f3ca6a6c779 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -261,16 +261,6 @@ pub fn upcast_choices<'tcx>( supertraits(tcx, source_trait_ref).filter(|r| r.def_id() == target_trait_def_id).collect() } -/// Given a trait `trait_ref`, returns the number of vtable entries -/// that come from `trait_ref`, excluding its supertraits. Used in -/// computing the vtable base for an upcast trait of a trait object. -pub fn count_own_vtable_entries<'tcx>( - tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, -) -> usize { - tcx.own_existential_vtable_entries(trait_ref.def_id()).len() -} - /// Given an upcast trait object described by `object`, returns the /// index of the method `method_def_id` (which should be part of /// `object.upcast_trait_ref`) within the vtable for `object`. diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs new file mode 100644 index 00000000000..41ce6cdf789 --- /dev/null +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -0,0 +1,386 @@ +use crate::errors::DumpVTableEntries; +use crate::traits::{impossible_predicates, is_vtable_safe_method}; +use rustc_hir::def_id::DefId; +use rustc_hir::lang_items::LangItem; +use rustc_infer::traits::util::PredicateSet; +use rustc_infer::traits::ImplSource; +use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::InternalSubsts; +use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry}; +use rustc_span::{sym, Span}; +use smallvec::SmallVec; + +use std::fmt::Debug; +use std::ops::ControlFlow; + +#[derive(Clone, Debug)] +pub(super) enum VtblSegment<'tcx> { + MetadataDSA, + TraitOwnEntries { trait_ref: ty::PolyTraitRef<'tcx>, emit_vptr: bool }, +} + +/// Prepare the segments for a vtable +pub(super) fn prepare_vtable_segments<'tcx, T>( + tcx: TyCtxt<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, + mut segment_visitor: impl FnMut(VtblSegment<'tcx>) -> ControlFlow<T>, +) -> Option<T> { + // The following constraints holds for the final arrangement. + // 1. The whole virtual table of the first direct super trait is included as the + // the prefix. If this trait doesn't have any super traits, then this step + // consists of the dsa metadata. + // 2. Then comes the proper pointer metadata(vptr) and all own methods for all + // other super traits except those already included as part of the first + // direct super trait virtual table. + // 3. finally, the own methods of this trait. + + // This has the advantage that trait upcasting to the first direct super trait on each level + // is zero cost, and to another trait includes only replacing the pointer with one level indirection, + // while not using too much extra memory. + + // For a single inheritance relationship like this, + // D --> C --> B --> A + // The resulting vtable will consists of these segments: + // DSA, A, B, C, D + + // For a multiple inheritance relationship like this, + // D --> C --> A + // \-> B + // The resulting vtable will consists of these segments: + // DSA, A, B, B-vptr, C, D + + // For a diamond inheritance relationship like this, + // D --> B --> A + // \-> C -/ + // The resulting vtable will consists of these segments: + // DSA, A, B, C, C-vptr, D + + // For a more complex inheritance relationship like this: + // O --> G --> C --> A + // \ \ \-> B + // | |-> F --> D + // | \-> E + // |-> N --> J --> H + // \ \-> I + // |-> M --> K + // \-> L + // The resulting vtable will consists of these segments: + // DSA, A, B, B-vptr, C, D, D-vptr, E, E-vptr, F, F-vptr, G, + // H, H-vptr, I, I-vptr, J, J-vptr, K, K-vptr, L, L-vptr, M, M-vptr, + // N, N-vptr, O + + // emit dsa segment first. + if let ControlFlow::Break(v) = (segment_visitor)(VtblSegment::MetadataDSA) { + return Some(v); + } + + let mut emit_vptr_on_new_entry = false; + let mut visited = PredicateSet::new(tcx); + let predicate = trait_ref.without_const().to_predicate(tcx); + let mut stack: SmallVec<[(ty::PolyTraitRef<'tcx>, _, _); 5]> = + smallvec![(trait_ref, emit_vptr_on_new_entry, None)]; + visited.insert(predicate); + + // the main traversal loop: + // basically we want to cut the inheritance directed graph into a few non-overlapping slices of nodes + // that each node is emitted after all its descendents have been emitted. + // so we convert the directed graph into a tree by skipping all previously visited nodes using a visited set. + // this is done on the fly. + // Each loop run emits a slice - it starts by find a "childless" unvisited node, backtracking upwards, and it + // stops after it finds a node that has a next-sibling node. + // This next-sibling node will used as the starting point of next slice. + + // Example: + // For a diamond inheritance relationship like this, + // D#1 --> B#0 --> A#0 + // \-> C#1 -/ + + // Starting point 0 stack [D] + // Loop run #0: Stack after diving in is [D B A], A is "childless" + // after this point, all newly visited nodes won't have a vtable that equals to a prefix of this one. + // Loop run #0: Emitting the slice [B A] (in reverse order), B has a next-sibling node, so this slice stops here. + // Loop run #0: Stack after exiting out is [D C], C is the next starting point. + // Loop run #1: Stack after diving in is [D C], C is "childless", since its child A is skipped(already emitted). + // Loop run #1: Emitting the slice [D C] (in reverse order). No one has a next-sibling node. + // Loop run #1: Stack after exiting out is []. Now the function exits. + + loop { + // dive deeper into the stack, recording the path + 'diving_in: loop { + if let Some((inner_most_trait_ref, _, _)) = stack.last() { + let inner_most_trait_ref = *inner_most_trait_ref; + let mut direct_super_traits_iter = tcx + .super_predicates_of(inner_most_trait_ref.def_id()) + .predicates + .into_iter() + .filter_map(move |(pred, _)| { + pred.subst_supertrait(tcx, &inner_most_trait_ref).to_opt_poly_trait_pred() + }); + + 'diving_in_skip_visited_traits: loop { + if let Some(next_super_trait) = direct_super_traits_iter.next() { + if visited.insert(next_super_trait.to_predicate(tcx)) { + // We're throwing away potential constness of super traits here. + // FIXME: handle ~const super traits + let next_super_trait = next_super_trait.map_bound(|t| t.trait_ref); + stack.push(( + next_super_trait, + emit_vptr_on_new_entry, + Some(direct_super_traits_iter), + )); + break 'diving_in_skip_visited_traits; + } else { + continue 'diving_in_skip_visited_traits; + } + } else { + break 'diving_in; + } + } + } + } + + // Other than the left-most path, vptr should be emitted for each trait. + emit_vptr_on_new_entry = true; + + // emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level. + 'exiting_out: loop { + if let Some((inner_most_trait_ref, emit_vptr, siblings_opt)) = stack.last_mut() { + if let ControlFlow::Break(v) = (segment_visitor)(VtblSegment::TraitOwnEntries { + trait_ref: *inner_most_trait_ref, + emit_vptr: *emit_vptr, + }) { + return Some(v); + } + + 'exiting_out_skip_visited_traits: loop { + if let Some(siblings) = siblings_opt { + if let Some(next_inner_most_trait_ref) = siblings.next() { + if visited.insert(next_inner_most_trait_ref.to_predicate(tcx)) { + // We're throwing away potential constness of super traits here. + // FIXME: handle ~const super traits + let next_inner_most_trait_ref = + next_inner_most_trait_ref.map_bound(|t| t.trait_ref); + *inner_most_trait_ref = next_inner_most_trait_ref; + *emit_vptr = emit_vptr_on_new_entry; + break 'exiting_out; + } else { + continue 'exiting_out_skip_visited_traits; + } + } + } + stack.pop(); + continue 'exiting_out; + } + } + // all done + return None; + } + } +} + +fn dump_vtable_entries<'tcx>( + tcx: TyCtxt<'tcx>, + sp: Span, + trait_ref: ty::PolyTraitRef<'tcx>, + entries: &[VtblEntry<'tcx>], +) { + tcx.sess.emit_err(DumpVTableEntries { + span: sp, + trait_ref, + entries: format!("{:#?}", entries), + }); +} + +fn own_existential_vtable_entries<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> &'tcx [DefId] { + let trait_methods = tcx + .associated_items(trait_def_id) + .in_definition_order() + .filter(|item| item.kind == ty::AssocKind::Fn); + // Now list each method's DefId (for within its trait). + let own_entries = trait_methods.filter_map(move |trait_method| { + debug!("own_existential_vtable_entry: trait_method={:?}", trait_method); + let def_id = trait_method.def_id; + + // Some methods cannot be called on an object; skip those. + if !is_vtable_safe_method(tcx, trait_def_id, &trait_method) { + debug!("own_existential_vtable_entry: not vtable safe"); + return None; + } + + Some(def_id) + }); + + tcx.arena.alloc_from_iter(own_entries.into_iter()) +} + +/// Given a trait `trait_ref`, iterates the vtable entries +/// that come from `trait_ref`, including its supertraits. +fn vtable_entries<'tcx>( + tcx: TyCtxt<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, +) -> &'tcx [VtblEntry<'tcx>] { + debug!("vtable_entries({:?})", trait_ref); + + let mut entries = vec![]; + + let vtable_segment_callback = |segment| -> ControlFlow<()> { + match segment { + VtblSegment::MetadataDSA => { + entries.extend(TyCtxt::COMMON_VTABLE_ENTRIES); + } + VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { + let existential_trait_ref = trait_ref + .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + + // Lookup the shape of vtable for the trait. + let own_existential_entries = + tcx.own_existential_vtable_entries(existential_trait_ref.def_id()); + + let own_entries = own_existential_entries.iter().copied().map(|def_id| { + debug!("vtable_entries: trait_method={:?}", def_id); + + // The method may have some early-bound lifetimes; add regions for those. + let substs = trait_ref.map_bound(|trait_ref| { + InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind { + GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + GenericParamDefKind::Type { .. } + | GenericParamDefKind::Const { .. } => { + trait_ref.substs[param.index as usize] + } + }) + }); + + // The trait type may have higher-ranked lifetimes in it; + // erase them if they appear, so that we get the type + // at some particular call site. + let substs = tcx + .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), substs); + + // It's possible that the method relies on where-clauses that + // do not hold for this particular set of type parameters. + // Note that this method could then never be called, so we + // do not want to try and codegen it, in that case (see #23435). + let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); + if impossible_predicates(tcx, predicates.predicates) { + debug!("vtable_entries: predicates do not hold"); + return VtblEntry::Vacant; + } + + let instance = ty::Instance::resolve_for_vtable( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + substs, + ) + .expect("resolution failed during building vtable representation"); + VtblEntry::Method(instance) + }); + + entries.extend(own_entries); + + if emit_vptr { + entries.push(VtblEntry::TraitVPtr(trait_ref)); + } + } + } + + ControlFlow::Continue(()) + }; + + let _ = prepare_vtable_segments(tcx, trait_ref, vtable_segment_callback); + + if tcx.has_attr(trait_ref.def_id(), sym::rustc_dump_vtable) { + let sp = tcx.def_span(trait_ref.def_id()); + dump_vtable_entries(tcx, sp, trait_ref, &entries); + } + + tcx.arena.alloc_from_iter(entries.into_iter()) +} + +/// Find slot base for trait methods within vtable entries of another trait +pub(super) fn vtable_trait_first_method_offset<'tcx>( + tcx: TyCtxt<'tcx>, + key: ( + ty::PolyTraitRef<'tcx>, // trait_to_be_found + ty::PolyTraitRef<'tcx>, // trait_owning_vtable + ), +) -> usize { + let (trait_to_be_found, trait_owning_vtable) = key; + + // #90177 + let trait_to_be_found_erased = tcx.erase_regions(trait_to_be_found); + + let vtable_segment_callback = { + let mut vtable_base = 0; + + move |segment| { + match segment { + VtblSegment::MetadataDSA => { + vtable_base += TyCtxt::COMMON_VTABLE_ENTRIES.len(); + } + VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { + if tcx.erase_regions(trait_ref) == trait_to_be_found_erased { + return ControlFlow::Break(vtable_base); + } + vtable_base += count_own_vtable_entries(tcx, trait_ref); + if emit_vptr { + vtable_base += 1; + } + } + } + ControlFlow::Continue(()) + } + }; + + if let Some(vtable_base) = + prepare_vtable_segments(tcx, trait_owning_vtable, vtable_segment_callback) + { + vtable_base + } else { + bug!("Failed to find info for expected trait in vtable"); + } +} + +/// Find slot offset for trait vptr within vtable entries of another trait +pub(crate) fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( + tcx: TyCtxt<'tcx>, + key: ( + Ty<'tcx>, // trait object type whose trait owning vtable + Ty<'tcx>, // trait object for supertrait + ), +) -> Option<usize> { + let (source, target) = key; + assert!(matches!(&source.kind(), &ty::Dynamic(..)) && !source.needs_infer()); + assert!(matches!(&target.kind(), &ty::Dynamic(..)) && !target.needs_infer()); + + // this has been typecked-before, so diagnostics is not really needed. + let unsize_trait_did = tcx.require_lang_item(LangItem::Unsize, None); + + let trait_ref = tcx.mk_trait_ref(unsize_trait_did, [source, target]); + + match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) { + Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => { + implsrc_traitcasting.vtable_vptr_slot + } + otherwise => bug!("expected TraitUpcasting candidate, got {otherwise:?}"), + } +} + +/// Given a trait `trait_ref`, returns the number of vtable entries +/// that come from `trait_ref`, excluding its supertraits. Used in +/// computing the vtable base for an upcast trait of a trait object. +pub(crate) fn count_own_vtable_entries<'tcx>( + tcx: TyCtxt<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, +) -> usize { + tcx.own_existential_vtable_entries(trait_ref.def_id()).len() +} + +pub(super) fn provide(providers: &mut ty::query::Providers) { + *providers = ty::query::Providers { + own_existential_vtable_entries, + vtable_entries, + vtable_trait_upcasting_coercion_new_vptr_slot, + ..*providers + }; +} diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 0102d268b42..f8f74b732ef 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -3,15 +3,15 @@ // seems likely that they should eventually be merged into more // general routines. -use crate::infer::{DefiningAnchor, TyCtxtInferExt}; -use crate::traits::error_reporting::TypeErrCtxtExt; -use crate::traits::{ - ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt, - Unimplemented, -}; +use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; use rustc_infer::traits::FulfillmentErrorCode; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::{self, TyCtxt}; +use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::traits::{ + ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt, + Unimplemented, +}; /// Attempts to resolve an obligation to an `ImplSource`. The result is /// a shallow `ImplSource` resolution, meaning that we do not diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index 0ffa92f1ad5..9aa26667e7b 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -12,6 +12,7 @@ extern crate tracing; extern crate rustc_middle; mod chalk; +mod codegen; mod dropck_outlives; mod evaluate_obligation; mod implied_outlives_bounds; @@ -31,4 +32,5 @@ pub fn provide(p: &mut Providers) { normalize_projection_ty::provide(p); normalize_erasing_regions::provide(p); type_op::provide(p); + p.codegen_select_candidate = codegen::codegen_select_candidate; } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 73c7eb6992f..d644cbccea1 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -85,7 +85,7 @@ fn fn_sig_for_fn_abi<'tcx>( bound_vars, ) } - ty::Generator(_, substs, _) => { + ty::Generator(did, substs, _) => { let sig = substs.as_generator().poly_sig(); let bound_vars = tcx.mk_bound_variable_kinds( @@ -104,10 +104,22 @@ fn fn_sig_for_fn_abi<'tcx>( let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs); let sig = sig.skip_binder(); - let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); - let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); - let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); + // The `FnSig` and the `ret_ty` here is for a generators main + // `Generator::resume(...) -> GeneratorState` function in case we + // have an ordinary generator, or the `Future::poll(...) -> Poll` + // function in case this is a special generator backing an async construct. + let ret_ty = if tcx.generator_is_async(did) { + let state_did = tcx.require_lang_item(LangItem::Poll, None); + let state_adt_ref = tcx.adt_def(state_did); + let state_substs = tcx.intern_substs(&[sig.return_ty.into()]); + tcx.mk_adt(state_adt_ref, state_substs) + } else { + let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); + let state_adt_ref = tcx.adt_def(state_did); + let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); + tcx.mk_adt(state_adt_ref, state_substs) + }; + ty::Binder::bind_with_vars( tcx.mk_fn_sig( [env_ty, sig.resume_ty].iter(), diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index fbc055b5d23..f4672a70072 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -1,3 +1,4 @@ +use hir::def_id::DefId; use rustc_hir as hir; use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; @@ -6,7 +7,7 @@ use rustc_middle::ty::layout::{ IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, }; use rustc_middle::ty::{ - self, subst::SubstsRef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable, + self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable, }; use rustc_session::{DataTypeKind, FieldInfo, SizeKind, VariantInfo}; use rustc_span::symbol::Symbol; @@ -814,27 +815,39 @@ fn record_layout_for_printing_outlined<'tcx>( ); }; - let adt_def = match *layout.ty.kind() { - ty::Adt(ref adt_def, _) => { + match *layout.ty.kind() { + ty::Adt(adt_def, _) => { debug!("print-type-size t: `{:?}` process adt", layout.ty); - adt_def + let adt_kind = adt_def.adt_kind(); + let adt_packed = adt_def.repr().pack.is_some(); + let (variant_infos, opt_discr_size) = variant_info_for_adt(cx, layout, adt_def); + record(adt_kind.into(), adt_packed, opt_discr_size, variant_infos); + } + + ty::Generator(def_id, substs, _) => { + debug!("print-type-size t: `{:?}` record generator", layout.ty); + // Generators always have a begin/poisoned/end state with additional suspend points + let (variant_infos, opt_discr_size) = + variant_info_for_generator(cx, layout, def_id, substs); + record(DataTypeKind::Generator, false, opt_discr_size, variant_infos); } ty::Closure(..) => { debug!("print-type-size t: `{:?}` record closure", layout.ty); record(DataTypeKind::Closure, false, None, vec![]); - return; } _ => { debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty); - return; } }; +} - let adt_kind = adt_def.adt_kind(); - let adt_packed = adt_def.repr().pack.is_some(); - +fn variant_info_for_adt<'tcx>( + cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, + layout: TyAndLayout<'tcx>, + adt_def: AdtDef<'tcx>, +) -> (Vec<VariantInfo>, Option<Size>) { let build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| { let mut min_size = Size::ZERO; let field_info: Vec<_> = flds @@ -843,10 +856,7 @@ fn record_layout_for_printing_outlined<'tcx>( .map(|(i, &name)| { let field_layout = layout.field(cx, i); let offset = layout.fields.offset(i); - let field_end = offset + field_layout.size; - if min_size < field_end { - min_size = field_end; - } + min_size = min_size.max(offset + field_layout.size); FieldInfo { name, offset: offset.bytes(), @@ -871,16 +881,9 @@ fn record_layout_for_printing_outlined<'tcx>( debug!("print-type-size `{:#?}` variant {}", layout, adt_def.variant(index).name); let variant_def = &adt_def.variant(index); let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect(); - record( - adt_kind.into(), - adt_packed, - None, - vec![build_variant_info(Some(variant_def.name), &fields, layout)], - ); + (vec![build_variant_info(Some(variant_def.name), &fields, layout)], None) } else { - // (This case arises for *empty* enums; so give it - // zero variants.) - record(adt_kind.into(), adt_packed, None, vec![]); + (vec![], None) } } @@ -898,15 +901,101 @@ fn record_layout_for_printing_outlined<'tcx>( build_variant_info(Some(variant_def.name), &fields, layout.for_variant(cx, i)) }) .collect(); - record( - adt_kind.into(), - adt_packed, + + ( + variant_infos, match tag_encoding { TagEncoding::Direct => Some(tag.size(cx)), _ => None, }, - variant_infos, - ); + ) } } } + +fn variant_info_for_generator<'tcx>( + cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, + layout: TyAndLayout<'tcx>, + def_id: DefId, + substs: ty::SubstsRef<'tcx>, +) -> (Vec<VariantInfo>, Option<Size>) { + let Variants::Multiple { tag, ref tag_encoding, .. } = layout.variants else { + return (vec![], None); + }; + + let (generator, state_specific_names) = cx.tcx.generator_layout_and_saved_local_names(def_id); + let upvar_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); + + let mut upvars_size = Size::ZERO; + let upvar_fields: Vec<_> = substs + .as_generator() + .upvar_tys() + .zip(upvar_names) + .enumerate() + .map(|(field_idx, (_, name))| { + let field_layout = layout.field(cx, field_idx); + let offset = layout.fields.offset(field_idx); + upvars_size = upvars_size.max(offset + field_layout.size); + FieldInfo { + name: Symbol::intern(&name), + offset: offset.bytes(), + size: field_layout.size.bytes(), + align: field_layout.align.abi.bytes(), + } + }) + .collect(); + + let variant_infos: Vec<_> = generator + .variant_fields + .iter_enumerated() + .map(|(variant_idx, variant_def)| { + let variant_layout = layout.for_variant(cx, variant_idx); + let mut variant_size = Size::ZERO; + let fields = variant_def + .iter() + .enumerate() + .map(|(field_idx, local)| { + let field_layout = variant_layout.field(cx, field_idx); + let offset = variant_layout.fields.offset(field_idx); + // The struct is as large as the last field's end + variant_size = variant_size.max(offset + field_layout.size); + FieldInfo { + name: state_specific_names.get(*local).copied().flatten().unwrap_or( + Symbol::intern(&format!(".generator_field{}", local.as_usize())), + ), + offset: offset.bytes(), + size: field_layout.size.bytes(), + align: field_layout.align.abi.bytes(), + } + }) + .chain(upvar_fields.iter().copied()) + .collect(); + + // If the variant has no state-specific fields, then it's the size of the upvars. + if variant_size == Size::ZERO { + variant_size = upvars_size; + } + // We need to add the discriminant size back into min_size, since it is subtracted + // later during printing. + variant_size += match tag_encoding { + TagEncoding::Direct => tag.size(cx), + _ => Size::ZERO, + }; + + VariantInfo { + name: Some(Symbol::intern(&ty::GeneratorSubsts::variant_name(variant_idx))), + kind: SizeKind::Exact, + size: variant_size.bytes(), + align: variant_layout.align.abi.bytes(), + fields, + } + }) + .collect(); + ( + variant_infos, + match tag_encoding { + TagEncoding::Direct => Some(tag.size(cx)), + _ => None, + }, + ) +} diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index cce5a79ddc8..7ad5cbc01cc 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -29,6 +29,7 @@ mod layout; mod layout_sanity_check; mod needs_drop; pub mod representability; +mod structural_match; mod ty; pub fn provide(providers: &mut Providers) { @@ -42,4 +43,5 @@ pub fn provide(providers: &mut Providers) { representability::provide(providers); ty::provide(providers); instance::provide(providers); + structural_match::provide(providers); } diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs new file mode 100644 index 00000000000..a55bb7e7e90 --- /dev/null +++ b/compiler/rustc_ty_utils/src/structural_match.rs @@ -0,0 +1,44 @@ +use rustc_hir::lang_items::LangItem; +use rustc_middle::ty::query::Providers; +use rustc_middle::ty::{self, Ty, TyCtxt}; + +use rustc_infer::infer::TyCtxtInferExt; +use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; + +/// This method returns true if and only if `adt_ty` itself has been marked as +/// eligible for structural-match: namely, if it implements both +/// `StructuralPartialEq` and `StructuralEq` (which are respectively injected by +/// `#[derive(PartialEq)]` and `#[derive(Eq)]`). +/// +/// Note that this does *not* recursively check if the substructure of `adt_ty` +/// implements the traits. +fn has_structural_eq_impls<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool { + let ref infcx = tcx.infer_ctxt().build(); + let cause = ObligationCause::dummy(); + + let ocx = ObligationCtxt::new(infcx); + // require `#[derive(PartialEq)]` + let structural_peq_def_id = + infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span)); + ocx.register_bound(cause.clone(), ty::ParamEnv::empty(), adt_ty, structural_peq_def_id); + // for now, require `#[derive(Eq)]`. (Doing so is a hack to work around + // the type `for<'a> fn(&'a ())` failing to implement `Eq` itself.) + let structural_teq_def_id = + infcx.tcx.require_lang_item(LangItem::StructuralTeq, Some(cause.span)); + ocx.register_bound(cause, ty::ParamEnv::empty(), adt_ty, structural_teq_def_id); + + // We deliberately skip *reporting* fulfillment errors (via + // `report_fulfillment_errors`), for two reasons: + // + // 1. The error messages would mention `std::marker::StructuralPartialEq` + // (a trait which is solely meant as an implementation detail + // for now), and + // + // 2. We are sometimes doing future-incompatibility lints for + // now, so we do not want unconditional errors here. + ocx.select_all_or_error().is_empty() +} + +pub fn provide(providers: &mut Providers) { + providers.has_structural_eq_impls = has_structural_eq_impls; +} diff --git a/config.toml.example b/config.toml.example index ca54cbd2d68..5e1d2f2e314 100644 --- a/config.toml.example +++ b/config.toml.example @@ -35,9 +35,6 @@ changelog-seen = 2 # Unless you're developing for a target where Rust CI doesn't build a compiler # toolchain or changing LLVM locally, you probably want to set this to true. # -# This is false by default so that distributions don't unexpectedly download -# LLVM from the internet. -# # All tier 1 targets are currently supported; set this to `"if-available"` if # you are not sure whether you're on a tier 1 target. # @@ -45,7 +42,9 @@ changelog-seen = 2 # # Note that many of the LLVM options are not currently supported for # downloading. Currently only the "assertions" option can be toggled. -#download-ci-llvm = false +# +# Defaults to "if-available" when `channel = "dev"` and "false" otherwise. +#download-ci-llvm = "if-available" # Indicates whether LLVM rebuild should be skipped when running bootstrap. If # this is `false` then the compiler's LLVM will be rebuilt whenever the built diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index 55f6138cd0f..e54880e8652 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -25,6 +25,10 @@ impl<T, A: Allocator> IntoIter<T, A> { pub(super) fn new(inner: VecDeque<T, A>) -> Self { IntoIter { inner } } + + pub(super) fn into_vecdeque(self) -> VecDeque<T, A> { + self.inner + } } #[stable(feature = "collection_debug", since = "1.17.0")] diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 4866c53e7d5..4b9bd74d392 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -55,6 +55,10 @@ use self::spec_extend::SpecExtend; mod spec_extend; +use self::spec_from_iter::SpecFromIter; + +mod spec_from_iter; + #[cfg(test)] mod tests; @@ -586,6 +590,38 @@ impl<T, A: Allocator> VecDeque<T, A> { VecDeque { head: 0, len: 0, buf: RawVec::with_capacity_in(capacity, alloc) } } + /// Creates a `VecDeque` from a raw allocation, when the initialized + /// part of that allocation forms a *contiguous* subslice thereof. + /// + /// For use by `vec::IntoIter::into_vecdeque` + /// + /// # Safety + /// + /// All the usual requirements on the allocated memory like in + /// `Vec::from_raw_parts_in`, but takes a *range* of elements that are + /// initialized rather than only supporting `0..len`. Requires that + /// `initialized.start` ≤ `initialized.end` ≤ `capacity`. + #[inline] + pub(crate) unsafe fn from_contiguous_raw_parts_in( + ptr: *mut T, + initialized: Range<usize>, + capacity: usize, + alloc: A, + ) -> Self { + debug_assert!(initialized.start <= initialized.end); + debug_assert!(initialized.end <= capacity); + + // SAFETY: Our safety precondition guarantees the range length won't wrap, + // and that the allocation is valid for use in `RawVec`. + unsafe { + VecDeque { + head: initialized.start, + len: initialized.end.unchecked_sub(initialized.start), + buf: RawVec::from_raw_parts_in(ptr, capacity, alloc), + } + } + } + /// Provides a reference to the element at the given index. /// /// Element at index 0 is the front of the queue. @@ -2699,18 +2735,8 @@ impl<T, A: Allocator> IndexMut<usize> for VecDeque<T, A> { #[stable(feature = "rust1", since = "1.0.0")] impl<T> FromIterator<T> for VecDeque<T> { - #[inline] fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> VecDeque<T> { - // Since converting is O(1) now, might as well re-use that logic - // (including things like the `vec::IntoIter`→`Vec` specialization) - // especially as that could save us some monomorphiziation work - // if one uses the same iterators (like slice ones) with both. - return from_iter_via_vec(iter.into_iter()); - - #[inline] - fn from_iter_via_vec<U>(iter: impl Iterator<Item = U>) -> VecDeque<U> { - Vec::from_iter(iter).into() - } + SpecFromIter::spec_from_iter(iter.into_iter()) } } diff --git a/library/alloc/src/collections/vec_deque/spec_from_iter.rs b/library/alloc/src/collections/vec_deque/spec_from_iter.rs new file mode 100644 index 00000000000..7650492ebda --- /dev/null +++ b/library/alloc/src/collections/vec_deque/spec_from_iter.rs @@ -0,0 +1,33 @@ +use super::{IntoIter, VecDeque}; + +/// Specialization trait used for `VecDeque::from_iter` +pub(super) trait SpecFromIter<T, I> { + fn spec_from_iter(iter: I) -> Self; +} + +impl<T, I> SpecFromIter<T, I> for VecDeque<T> +where + I: Iterator<Item = T>, +{ + default fn spec_from_iter(iterator: I) -> Self { + // Since converting is O(1) now, just re-use the `Vec` logic for + // anything where we can't do something extra-special for `VecDeque`, + // especially as that could save us some monomorphiziation work + // if one uses the same iterators (like slice ones) with both. + crate::vec::Vec::from_iter(iterator).into() + } +} + +impl<T> SpecFromIter<T, crate::vec::IntoIter<T>> for VecDeque<T> { + #[inline] + fn spec_from_iter(iterator: crate::vec::IntoIter<T>) -> Self { + iterator.into_vecdeque() + } +} + +impl<T> SpecFromIter<T, IntoIter<T>> for VecDeque<T> { + #[inline] + fn spec_from_iter(iterator: IntoIter<T>) -> Self { + iterator.into_vecdeque() + } +} diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 02cc7691a82..6bcde6d899c 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -1,6 +1,8 @@ #[cfg(not(no_global_oom_handling))] use super::AsVecIntoIter; use crate::alloc::{Allocator, Global}; +#[cfg(not(no_global_oom_handling))] +use crate::collections::VecDeque; use crate::raw_vec::RawVec; use core::array; use core::fmt; @@ -132,6 +134,33 @@ impl<T, A: Allocator> IntoIter<T, A> { pub(crate) fn forget_remaining_elements(&mut self) { self.ptr = self.end; } + + #[cfg(not(no_global_oom_handling))] + #[inline] + pub(crate) fn into_vecdeque(self) -> VecDeque<T, A> { + // Keep our `Drop` impl from dropping the elements and the allocator + let mut this = ManuallyDrop::new(self); + + // SAFETY: This allocation originally came from a `Vec`, so it passes + // all those checks. We have `this.buf` ≤ `this.ptr` ≤ `this.end`, + // so the `sub_ptr`s below cannot wrap, and will produce a well-formed + // range. `end` ≤ `buf + cap`, so the range will be in-bounds. + // Taking `alloc` is ok because nothing else is going to look at it, + // since our `Drop` impl isn't going to run so there's no more code. + unsafe { + let buf = this.buf.as_ptr(); + let initialized = if T::IS_ZST { + // All the pointers are the same for ZSTs, so it's fine to + // say that they're all at the beginning of the "allocation". + 0..this.len() + } else { + this.ptr.sub_ptr(buf)..this.end.sub_ptr(buf) + }; + let cap = this.cap; + let alloc = ManuallyDrop::take(&mut this.alloc); + VecDeque::from_contiguous_raw_parts_in(buf, initialized, cap, alloc) + } + } } #[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")] diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index d04de5a074b..0b8f5281b78 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -1736,3 +1736,39 @@ fn test_resize_keeps_reserved_space_from_item() { d.resize(1, v); assert_eq!(d[0].capacity(), 1234); } + +#[test] +fn test_collect_from_into_iter_keeps_allocation() { + let mut v = Vec::with_capacity(13); + v.extend(0..7); + check(v.as_ptr(), v.last().unwrap(), v.into_iter()); + + let mut v = VecDeque::with_capacity(13); + v.extend(0..7); + check(&v[0], &v[v.len() - 1], v.into_iter()); + + fn check(buf: *const i32, last: *const i32, mut it: impl Iterator<Item = i32>) { + assert_eq!(it.next(), Some(0)); + assert_eq!(it.next(), Some(1)); + + let mut v: VecDeque<i32> = it.collect(); + assert_eq!(v.capacity(), 13); + assert_eq!(v.as_slices().0.as_ptr(), buf.wrapping_add(2)); + assert_eq!(&v[v.len() - 1] as *const _, last); + + assert_eq!(v.as_slices(), ([2, 3, 4, 5, 6].as_slice(), [].as_slice())); + v.push_front(7); + assert_eq!(v.as_slices(), ([7, 2, 3, 4, 5, 6].as_slice(), [].as_slice())); + v.push_front(8); + assert_eq!(v.as_slices(), ([8, 7, 2, 3, 4, 5, 6].as_slice(), [].as_slice())); + + // Now that we've adding thing in place of the two that we removed from + // the front of the iterator, we're back to matching the buffer pointer. + assert_eq!(v.as_slices().0.as_ptr(), buf); + assert_eq!(&v[v.len() - 1] as *const _, last); + + v.push_front(9); + assert_eq!(v.as_slices(), ([9].as_slice(), [8, 7, 2, 3, 4, 5, 6].as_slice())); + assert_eq!(v.capacity(), 13); + } +} diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 06dca7e59a2..398437d9a02 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -176,7 +176,6 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> { /// are implemented in `traits::SelectionContext::copy_clone_conditions()` /// in `rustc_trait_selection`. mod impls { - use super::Clone; macro_rules! impl_clone { @@ -185,7 +184,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] impl const Clone for $t { - #[inline] + #[inline(always)] fn clone(&self) -> Self { *self } @@ -213,7 +212,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] impl<T: ?Sized> const Clone for *const T { - #[inline] + #[inline(always)] fn clone(&self) -> Self { *self } @@ -222,7 +221,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] impl<T: ?Sized> const Clone for *mut T { - #[inline] + #[inline(always)] fn clone(&self) -> Self { *self } @@ -232,7 +231,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] impl<T: ?Sized> const Clone for &T { - #[inline] + #[inline(always)] #[rustc_diagnostic_item = "noop_method_clone"] fn clone(&self) -> Self { *self diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 33493964bad..f95b880df34 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -99,7 +99,7 @@ pub use num::FloatToInt; /// ``` #[stable(feature = "convert_id", since = "1.33.0")] #[rustc_const_stable(feature = "const_identity", since = "1.33.0")] -#[inline] +#[inline(always)] pub const fn identity<T>(x: T) -> T { x } @@ -789,6 +789,7 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl<T> AsRef<[T]> for [T] { + #[inline(always)] fn as_ref(&self) -> &[T] { self } @@ -796,6 +797,7 @@ impl<T> AsRef<[T]> for [T] { #[stable(feature = "rust1", since = "1.0.0")] impl<T> AsMut<[T]> for [T] { + #[inline(always)] fn as_mut(&mut self) -> &mut [T] { self } @@ -803,7 +805,7 @@ impl<T> AsMut<[T]> for [T] { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<str> for str { - #[inline] + #[inline(always)] fn as_ref(&self) -> &str { self } @@ -811,7 +813,7 @@ impl AsRef<str> for str { #[stable(feature = "as_mut_str_for_str", since = "1.51.0")] impl AsMut<str> for str { - #[inline] + #[inline(always)] fn as_mut(&mut self) -> &mut str { self } diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index c53175ba4f3..e8d724ab1ef 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -160,7 +160,7 @@ pub const unsafe fn unreachable_unchecked() -> ! { /// ``` /// /// [`thread::yield_now`]: ../../std/thread/fn.yield_now.html -#[inline] +#[inline(always)] #[stable(feature = "renamed_spin_loop", since = "1.49.0")] pub fn spin_loop() { #[cfg(target_arch = "x86")] @@ -345,6 +345,7 @@ pub const fn black_box<T>(dummy: T) -> T { #[unstable(feature = "hint_must_use", issue = "94745")] #[rustc_const_unstable(feature = "hint_must_use", issue = "94745")] #[must_use] // <-- :) +#[inline(always)] pub const fn must_use<T>(value: T) -> T { value } diff --git a/library/core/src/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs index 84d83ee3969..e31669b3924 100644 --- a/library/core/src/iter/traits/accum.rs +++ b/library/core/src/iter/traits/accum.rs @@ -10,6 +10,10 @@ use crate::num::Wrapping; /// [`sum()`]: Iterator::sum /// [`FromIterator`]: iter::FromIterator #[stable(feature = "iter_arith_traits", since = "1.12.0")] +#[rustc_on_unimplemented( + message = "a value of type `{Self}` cannot be made by summing an iterator over elements of type `{A}`", + label = "value of type `{Self}` cannot be made by summing a `std::iter::Iterator<Item={A}>`" +)] pub trait Sum<A = Self>: Sized { /// Method which takes an iterator and generates `Self` from the elements by /// "summing up" the items. @@ -27,6 +31,10 @@ pub trait Sum<A = Self>: Sized { /// [`product()`]: Iterator::product /// [`FromIterator`]: iter::FromIterator #[stable(feature = "iter_arith_traits", since = "1.12.0")] +#[rustc_on_unimplemented( + message = "a value of type `{Self}` cannot be made by multiplying all elements of type `{A}` from an iterator", + label = "value of type `{Self}` cannot be made by multiplying all elements from a `std::iter::Iterator<Item={A}>`" +)] pub trait Product<A = Self>: Sized { /// Method which takes an iterator and generates `Self` from the elements by /// multiplying the items. diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index b2328b001de..ac7f579ebb5 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -4,12 +4,14 @@ use crate::ascii; use crate::convert::TryInto; -use crate::error::Error; use crate::intrinsics; use crate::mem; use crate::ops::{Add, Mul, Sub}; use crate::str::FromStr; +#[cfg(not(no_fp_fmt_parse))] +use crate::error::Error; + // Used because the `?` operator is not allowed in a const context. macro_rules! try_opt { ($e:expr) => { diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index a5e5b13b336..eb2a92f4644 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -17,10 +17,10 @@ //! should have some resemblance to multiplication (and share expected //! properties like associativity). //! -//! Note that the `&&` and `||` operators short-circuit, i.e., they only -//! evaluate their second operand if it contributes to the result. Since this -//! behavior is not enforceable by traits, `&&` and `||` are not supported as -//! overloadable operators. +//! Note that the `&&` and `||` operators are currently not supported for +//! overloading. Due to their short circuiting nature, they require a different +//! design from traits for other operators like [`BitAnd`]. Designs for them are +//! under discussion. //! //! Many of the operators take their operands by value. In non-generic //! contexts involving built-in types, this is usually not a problem. diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 76603e1018d..d348135991a 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -45,7 +45,7 @@ impl<T: ?Sized> *const T { /// Casts to a pointer of another type. #[stable(feature = "ptr_cast", since = "1.38.0")] #[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")] - #[inline] + #[inline(always)] pub const fn cast<U>(self) -> *const U { self as _ } @@ -95,6 +95,7 @@ impl<T: ?Sized> *const T { /// refactored. #[stable(feature = "ptr_const_cast", since = "1.65.0")] #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")] + #[inline(always)] pub const fn cast_mut(self) -> *mut T { self as _ } @@ -126,6 +127,7 @@ impl<T: ?Sized> *const T { note = "replaced by the `exposed_addr` method, or update your code \ to follow the strict provenance rules using its APIs" )] + #[inline(always)] pub fn to_bits(self) -> usize where T: Sized, @@ -155,6 +157,7 @@ impl<T: ?Sized> *const T { your code to follow the strict provenance rules using its APIs" )] #[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function + #[inline(always)] pub fn from_bits(bits: usize) -> Self where T: Sized, @@ -186,7 +189,7 @@ impl<T: ?Sized> *const T { /// might change in the future (including possibly weakening this so it becomes wholly /// equivalent to `self as usize`). See the [module documentation][crate::ptr] for details. #[must_use] - #[inline] + #[inline(always)] #[unstable(feature = "strict_provenance", issue = "95228")] pub fn addr(self) -> usize where @@ -223,7 +226,7 @@ impl<T: ?Sized> *const T { /// /// [`from_exposed_addr`]: from_exposed_addr #[must_use] - #[inline] + #[inline(always)] #[unstable(feature = "strict_provenance", issue = "95228")] pub fn expose_addr(self) -> usize where diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 89b11637eca..48b2e88da28 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -613,7 +613,7 @@ pub const fn invalid_mut<T>(addr: usize) -> *mut T { /// This API and its claimed semantics are part of the Strict Provenance experiment, see the /// [module documentation][crate::ptr] for details. #[must_use] -#[inline] +#[inline(always)] #[unstable(feature = "strict_provenance", issue = "95228")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[allow(fuzzy_provenance_casts)] // this *is* the strict provenance API one should use instead @@ -651,7 +651,7 @@ where /// This API and its claimed semantics are part of the Strict Provenance experiment, see the /// [module documentation][crate::ptr] for details. #[must_use] -#[inline] +#[inline(always)] #[unstable(feature = "strict_provenance", issue = "95228")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[allow(fuzzy_provenance_casts)] // this *is* the strict provenance API one should use instead @@ -1769,7 +1769,7 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz /// (which is what the `PartialEq for &T` implementation does). /// /// When comparing wide pointers, both the address and the metadata are tested for equality. -/// However, note that comparing trait object pointers (`*const dyn Trait`) is unrealiable: pointers +/// However, note that comparing trait object pointers (`*const dyn Trait`) is unreliable: pointers /// to values of the same underlying type can compare inequal (because vtables are duplicated in /// multiple codegen units), and pointers to values of *different* underlying type can compare equal /// (since identical vtables can be deduplicated within a codegen unit). @@ -1801,7 +1801,7 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz /// assert!(!std::ptr::eq(&a[0..2], &a[1..3])); /// ``` #[stable(feature = "ptr_eq", since = "1.17.0")] -#[inline] +#[inline(always)] pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool { a == b } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index b03cad18e4a..c924a90b1ff 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -100,6 +100,7 @@ impl<T: ?Sized> *mut T { /// [`cast_mut`]: #method.cast_mut #[stable(feature = "ptr_const_cast", since = "1.65.0")] #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")] + #[inline(always)] pub const fn cast_const(self) -> *const T { self as _ } @@ -132,6 +133,7 @@ impl<T: ?Sized> *mut T { note = "replaced by the `exposed_addr` method, or update your code \ to follow the strict provenance rules using its APIs" )] + #[inline(always)] pub fn to_bits(self) -> usize where T: Sized, @@ -161,6 +163,7 @@ impl<T: ?Sized> *mut T { update your code to follow the strict provenance rules using its APIs" )] #[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function + #[inline(always)] pub fn from_bits(bits: usize) -> Self where T: Sized, @@ -192,7 +195,7 @@ impl<T: ?Sized> *mut T { /// might change in the future (including possibly weakening this so it becomes wholly /// equivalent to `self as usize`). See the [module documentation][crate::ptr] for details. #[must_use] - #[inline] + #[inline(always)] #[unstable(feature = "strict_provenance", issue = "95228")] pub fn addr(self) -> usize where @@ -229,7 +232,7 @@ impl<T: ?Sized> *mut T { /// /// [`from_exposed_addr_mut`]: from_exposed_addr_mut #[must_use] - #[inline] + #[inline(always)] #[unstable(feature = "strict_provenance", issue = "95228")] pub fn expose_addr(self) -> usize where diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c18264d13eb..c4348169c78 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -330,7 +330,7 @@ impl<T: ?Sized> NonNull<T> { #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")] #[must_use] - #[inline] + #[inline(always)] pub const fn as_ptr(self) -> *mut T { self.pointer as *mut T } @@ -378,7 +378,7 @@ impl<T: ?Sized> NonNull<T> { #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[must_use] - #[inline] + #[inline(always)] pub const unsafe fn as_ref<'a>(&self) -> &'a T { // SAFETY: the caller must guarantee that `self` meets all the // requirements for a reference. @@ -429,7 +429,7 @@ impl<T: ?Sized> NonNull<T> { #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[must_use] - #[inline] + #[inline(always)] pub const unsafe fn as_mut<'a>(&mut self) -> &'a mut T { // SAFETY: the caller must guarantee that `self` meets all the // requirements for a mutable reference. @@ -703,7 +703,7 @@ impl<T> NonNull<[T]> { #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] impl<T: ?Sized> const Clone for NonNull<T> { - #[inline] + #[inline(always)] fn clone(&self) -> Self { *self } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 04486ed2d14..d9281a9252c 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -465,7 +465,7 @@ impl<T> [T] { /// [`as_mut_ptr`]: slice::as_mut_ptr #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")] - #[inline] + #[inline(always)] #[must_use] pub const fn as_ptr(&self) -> *const T { self as *const [T] as *const T @@ -495,7 +495,7 @@ impl<T> [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[rustc_allow_const_fn_unstable(const_mut_refs)] - #[inline] + #[inline(always)] #[must_use] pub const fn as_mut_ptr(&mut self) -> *mut T { self as *mut [T] as *mut T @@ -3468,10 +3468,11 @@ impl<T> [T] { /// maintained. /// /// This method splits the slice into three distinct slices: prefix, correctly aligned middle - /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest - /// length possible for a given type and input slice, but only your algorithm's performance - /// should depend on that, not its correctness. It is permissible for all of the input data to - /// be returned as the prefix or suffix slice. + /// slice of a new type, and the suffix slice. How exactly the slice is split up is not + /// specified; the middle part may be smaller than necessary. However, if this fails to return a + /// maximal middle part, that is because code is running in a context where performance does not + /// matter, such as a sanitizer attempting to find alignment bugs. Regular code running + /// in a default (debug or release) execution *will* return a maximal middle part. /// /// This method has no purpose when either input element `T` or output element `U` are /// zero-sized and will return the original slice without splitting anything. @@ -3529,10 +3530,11 @@ impl<T> [T] { /// types is maintained. /// /// This method splits the slice into three distinct slices: prefix, correctly aligned middle - /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest - /// length possible for a given type and input slice, but only your algorithm's performance - /// should depend on that, not its correctness. It is permissible for all of the input data to - /// be returned as the prefix or suffix slice. + /// slice of a new type, and the suffix slice. How exactly the slice is split up is not + /// specified; the middle part may be smaller than necessary. However, if this fails to return a + /// maximal middle part, that is because code is running in a context where performance does not + /// matter, such as a sanitizer attempting to find alignment bugs. Regular code running + /// in a default (debug or release) execution *will* return a maximal middle part. /// /// This method has no purpose when either input element `T` or output element `U` are /// zero-sized and will return the original slice without splitting anything. diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index c0167388713..45fd2caae52 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -396,7 +396,7 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rustc_str_as_ptr", since = "1.32.0")] #[must_use] - #[inline] + #[inline(always)] pub const fn as_ptr(&self) -> *const u8 { self as *const str as *const u8 } @@ -411,7 +411,7 @@ impl str { /// modified in a way that it remains valid UTF-8. #[stable(feature = "str_as_mut_ptr", since = "1.36.0")] #[must_use] - #[inline] + #[inline(always)] pub fn as_mut_ptr(&mut self) -> *mut u8 { self as *mut str as *mut u8 } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index b8959316de1..4748ac9d97e 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1551,3 +1551,19 @@ fn hiberfil_sys() { fs::metadata(hiberfil).unwrap(); assert_eq!(true, hiberfil.exists()); } + +/// Test that two different ways of obtaining the FileType give the same result. +/// Cf. https://github.com/rust-lang/rust/issues/104900 +#[test] +fn test_eq_direntry_metadata() { + let tmpdir = tmpdir(); + let file_path = tmpdir.join("file"); + File::create(file_path).unwrap(); + for e in fs::read_dir(tmpdir.path()).unwrap() { + let e = e.unwrap(); + let p = e.path(); + let ft1 = e.file_type().unwrap(); + let ft2 = p.metadata().unwrap().file_type(); + assert_eq!(ft1, ft2); + } +} diff --git a/library/std/src/sys/itron/condvar.rs b/library/std/src/sys/itron/condvar.rs index f70aa434e48..7a47cc6696a 100644 --- a/library/std/src/sys/itron/condvar.rs +++ b/library/std/src/sys/itron/condvar.rs @@ -71,7 +71,7 @@ impl Condvar { } } - unsafe { mutex.lock() }; + mutex.lock(); } pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { @@ -109,7 +109,7 @@ impl Condvar { // we woke up because of `notify_*`. let success = self.waiters.with_locked(|waiters| unsafe { !waiters.remove(waiter) }); - unsafe { mutex.lock() }; + mutex.lock(); success } } diff --git a/library/std/src/sys/itron/mutex.rs b/library/std/src/sys/itron/mutex.rs index f2eed8e771c..1f6cc419476 100644 --- a/library/std/src/sys/itron/mutex.rs +++ b/library/std/src/sys/itron/mutex.rs @@ -72,7 +72,7 @@ pub(super) struct MutexGuard<'a>(&'a Mutex); impl<'a> MutexGuard<'a> { #[inline] pub(super) fn lock(x: &'a Mutex) -> Self { - unsafe { x.lock() }; + x.lock(); Self(x) } } diff --git a/library/std/src/sys/itron/thread.rs b/library/std/src/sys/itron/thread.rs index d28f57f33be..c2b36680872 100644 --- a/library/std/src/sys/itron/thread.rs +++ b/library/std/src/sys/itron/thread.rs @@ -11,18 +11,25 @@ use crate::{ ffi::CStr, hint, io, mem::ManuallyDrop, + ptr::NonNull, sync::atomic::{AtomicUsize, Ordering}, sys::thread_local_dtor::run_dtors, time::Duration, }; pub struct Thread { - inner: ManuallyDrop<Box<ThreadInner>>, + p_inner: NonNull<ThreadInner>, /// The ID of the underlying task. task: abi::ID, } +// Safety: There's nothing in `Thread` that ties it to the original creator. It +// can be dropped by any threads. +unsafe impl Send for Thread {} +// Safety: `Thread` provides no methods that take `&self`. +unsafe impl Sync for Thread {} + /// State data shared between a parent thread and child thread. It's dropped on /// a transition to one of the final states. struct ThreadInner { @@ -90,8 +97,9 @@ impl Thread { }); unsafe extern "C" fn trampoline(exinf: isize) { + let p_inner: *mut ThreadInner = crate::ptr::from_exposed_addr_mut(exinf as usize); // Safety: `ThreadInner` is alive at this point - let inner = unsafe { &*(exinf as *const ThreadInner) }; + let inner = unsafe { &*p_inner }; // Safety: Since `trampoline` is called only once for each // `ThreadInner` and only `trampoline` touches `start`, @@ -119,13 +127,13 @@ impl Thread { // No one will ever join, so we'll ask the collector task to // delete the task. - // In this case, `inner`'s ownership has been moved to us, - // And we are responsible for dropping it. The acquire + // In this case, `*p_inner`'s ownership has been moved to + // us, and we are responsible for dropping it. The acquire // ordering is not necessary because the parent thread made // no memory access needing synchronization since the call // to `acre_tsk`. // Safety: See above. - let _ = unsafe { Box::from_raw(inner as *const _ as *mut ThreadInner) }; + let _ = unsafe { Box::from_raw(p_inner) }; // Safety: There are no pinned references to the stack unsafe { terminate_and_delete_current_task() }; @@ -162,13 +170,14 @@ impl Thread { } } - let inner_ptr = (&*inner) as *const ThreadInner; + // Safety: `Box::into_raw` returns a non-null pointer + let p_inner = unsafe { NonNull::new_unchecked(Box::into_raw(inner)) }; let new_task = ItronError::err_if_negative(unsafe { abi::acre_tsk(&abi::T_CTSK { // Activate this task immediately tskatr: abi::TA_ACT, - exinf: inner_ptr as abi::EXINF, + exinf: p_inner.as_ptr().expose_addr() as abi::EXINF, // The entry point task: Some(trampoline), // Inherit the calling task's base priority @@ -180,7 +189,7 @@ impl Thread { }) .map_err(|e| e.as_io_error())?; - Ok(Self { inner: ManuallyDrop::new(inner), task: new_task }) + Ok(Self { p_inner, task: new_task }) } pub fn yield_now() { @@ -197,8 +206,9 @@ impl Thread { } } - pub fn join(mut self) { - let inner = &*self.inner; + pub fn join(self) { + // Safety: `ThreadInner` is alive at this point + let inner = unsafe { self.p_inner.as_ref() }; // Get the current task ID. Panicking here would cause a resource leak, // so just abort on failure. let current_task = task::current_task_id_aborting(); @@ -243,8 +253,8 @@ impl Thread { unsafe { terminate_and_delete_task(self.task) }; // In either case, we are responsible for dropping `inner`. - // Safety: The contents of `self.inner` will not be accessed hereafter - let _inner = unsafe { ManuallyDrop::take(&mut self.inner) }; + // Safety: The contents of `*p_inner` will not be accessed hereafter + let _inner = unsafe { Box::from_raw(self.p_inner.as_ptr()) }; // Skip the destructor (because it would attempt to detach the thread) crate::mem::forget(self); @@ -253,13 +263,16 @@ impl Thread { impl Drop for Thread { fn drop(&mut self) { + // Safety: `ThreadInner` is alive at this point + let inner = unsafe { self.p_inner.as_ref() }; + // Detach the thread. - match self.inner.lifecycle.swap(LIFECYCLE_DETACHED_OR_JOINED, Ordering::Acquire) { + match inner.lifecycle.swap(LIFECYCLE_DETACHED_OR_JOINED, Ordering::Acquire) { LIFECYCLE_INIT => { // [INIT → DETACHED] // When the time comes, the child will figure out that no // one will ever join it. - // The ownership of `self.inner` is moved to the child thread. + // The ownership of `*p_inner` is moved to the child thread. // However, the release ordering is not necessary because we // made no memory access needing synchronization since the call // to `acre_tsk`. @@ -278,10 +291,9 @@ impl Drop for Thread { // delete by entering the `FINISHED` state. unsafe { terminate_and_delete_task(self.task) }; - // Wwe are responsible for dropping `inner`. - // Safety: The contents of `self.inner` will not be accessed - // hereafter - unsafe { ManuallyDrop::drop(&mut self.inner) }; + // Wwe are responsible for dropping `*p_inner`. + // Safety: The contents of `*p_inner` will not be accessed hereafter + let _ = unsafe { Box::from_raw(self.p_inner.as_ptr()) }; } _ => unsafe { hint::unreachable_unchecked() }, } diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs index 01e4ffe3dfc..63e070207cd 100644 --- a/library/std/src/sys/sgx/mod.rs +++ b/library/std/src/sys/sgx/mod.rs @@ -34,6 +34,7 @@ pub mod process; pub mod stdio; pub mod thread; pub mod thread_local_key; +pub mod thread_parker; pub mod time; mod condvar; diff --git a/library/std/src/sys/sgx/thread.rs b/library/std/src/sys/sgx/thread.rs index d745a619614..579f758c6cc 100644 --- a/library/std/src/sys/sgx/thread.rs +++ b/library/std/src/sys/sgx/thread.rs @@ -65,39 +65,36 @@ mod task_queue { /// execution. The signal is sent once all TLS destructors have finished at /// which point no new thread locals should be created. pub mod wait_notify { - use super::super::waitqueue::{SpinMutex, WaitQueue, WaitVariable}; + use super::super::thread_parker::Parker; + use crate::pin::Pin; use crate::sync::Arc; - pub struct Notifier(Arc<SpinMutex<WaitVariable<bool>>>); + pub struct Notifier(Arc<Parker>); impl Notifier { /// Notify the waiter. The waiter is either notified right away (if /// currently blocked in `Waiter::wait()`) or later when it calls the /// `Waiter::wait()` method. pub fn notify(self) { - let mut guard = self.0.lock(); - *guard.lock_var_mut() = true; - let _ = WaitQueue::notify_one(guard); + Pin::new(&*self.0).unpark() } } - pub struct Waiter(Arc<SpinMutex<WaitVariable<bool>>>); + pub struct Waiter(Arc<Parker>); impl Waiter { /// Wait for a notification. If `Notifier::notify()` has already been /// called, this will return immediately, otherwise the current thread /// is blocked until notified. pub fn wait(self) { - let guard = self.0.lock(); - if *guard.lock_var() { - return; - } - WaitQueue::wait(guard, || {}); + // This is not actually `unsafe`, but it uses the `Parker` API, + // which needs `unsafe` on some platforms. + unsafe { Pin::new(&*self.0).park() } } } pub fn new() -> (Notifier, Waiter) { - let inner = Arc::new(SpinMutex::new(WaitVariable::new(false))); + let inner = Arc::new(Parker::new_internal()); (Notifier(inner.clone()), Waiter(inner)) } } diff --git a/library/std/src/sys/sgx/thread_parker.rs b/library/std/src/sys/sgx/thread_parker.rs new file mode 100644 index 00000000000..1c55bcffb1e --- /dev/null +++ b/library/std/src/sys/sgx/thread_parker.rs @@ -0,0 +1,107 @@ +//! Thread parking based on SGX events. + +use super::abi::{thread, usercalls}; +use crate::io::ErrorKind; +use crate::pin::Pin; +use crate::ptr::{self, NonNull}; +use crate::sync::atomic::AtomicPtr; +use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; +use crate::time::Duration; +use fortanix_sgx_abi::{EV_UNPARK, WAIT_INDEFINITE}; + +// The TCS structure must be page-aligned (this is checked by EENTER), so these cannot +// be valid pointers +const EMPTY: *mut u8 = ptr::invalid_mut(1); +const NOTIFIED: *mut u8 = ptr::invalid_mut(2); + +pub struct Parker { + /// The park state. One of EMPTY, NOTIFIED or a TCS address. + /// A state change to NOTIFIED must be done with release ordering + /// and be observed with acquire ordering so that operations after + /// `thread::park` returns will not occur before the unpark message + /// was sent. + state: AtomicPtr<u8>, +} + +impl Parker { + /// Construct the thread parker. The UNIX parker implementation + /// requires this to happen in-place. + pub unsafe fn new(parker: *mut Parker) { + unsafe { parker.write(Parker::new_internal()) } + } + + pub(super) fn new_internal() -> Parker { + Parker { state: AtomicPtr::new(EMPTY) } + } + + // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. + pub unsafe fn park(self: Pin<&Self>) { + if self.state.load(Acquire) != NOTIFIED { + let mut prev = EMPTY; + loop { + // Guard against changing TCS addresses by always setting the state to + // the current value. + let tcs = thread::current().as_ptr(); + if self.state.compare_exchange(prev, tcs, Relaxed, Acquire).is_ok() { + let event = usercalls::wait(EV_UNPARK, WAIT_INDEFINITE).unwrap(); + assert!(event & EV_UNPARK == EV_UNPARK); + prev = tcs; + } else { + // The state was definitely changed by another thread at this point. + // The only time this occurs is when the state is changed to NOTIFIED. + // We observed this change with acquire ordering, so we can simply + // change the state to EMPTY with a relaxed store. + break; + } + } + } + + // At this point, the token was definately read with acquire ordering, + // so this can be a relaxed store. + self.state.store(EMPTY, Relaxed); + } + + // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. + pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) { + let timeout = u128::min(dur.as_nanos(), WAIT_INDEFINITE as u128 - 1) as u64; + let tcs = thread::current().as_ptr(); + + if self.state.load(Acquire) != NOTIFIED { + if self.state.compare_exchange(EMPTY, tcs, Relaxed, Acquire).is_ok() { + match usercalls::wait(EV_UNPARK, timeout) { + Ok(event) => assert!(event & EV_UNPARK == EV_UNPARK), + Err(e) => { + assert!(matches!(e.kind(), ErrorKind::TimedOut | ErrorKind::WouldBlock)) + } + } + + // Swap to provide acquire ordering even if the timeout occurred + // before the token was set. This situation can result in spurious + // wakeups on the next call to `park_timeout`, but it is better to let + // those be handled by the user than do some perhaps unnecessary, but + // always expensive guarding. + self.state.swap(EMPTY, Acquire); + return; + } + } + + // The token was already read with `acquire` ordering, this can be a store. + self.state.store(EMPTY, Relaxed); + } + + // This implementation doesn't require `Pin`, but other implementations do. + pub fn unpark(self: Pin<&Self>) { + let state = self.state.swap(NOTIFIED, Release); + + if !matches!(state, EMPTY | NOTIFIED) { + // There is a thread waiting, wake it up. + let tcs = NonNull::new(state).unwrap(); + // This will fail if the thread has already terminated or its TCS is destroyed + // by the time the signal is sent, but that is fine. If another thread receives + // the same TCS, it will receive this notification as a spurious wakeup, but + // all users of `wait` should and (internally) do guard against those where + // necessary. + let _ = usercalls::send(EV_UNPARK, Some(tcs)); + } + } +} diff --git a/library/std/src/sys/solid/io.rs b/library/std/src/sys/solid/io.rs index 9eb17a10daa..a862bb78702 100644 --- a/library/std/src/sys/solid/io.rs +++ b/library/std/src/sys/solid/io.rs @@ -75,3 +75,7 @@ impl<'a> IoSliceMut<'a> { unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) } } } + +pub fn is_terminal<T>(_: &T) -> bool { + false +} diff --git a/library/std/src/sys/solid/os.rs b/library/std/src/sys/solid/os.rs index 4906c62689d..6135921f0b5 100644 --- a/library/std/src/sys/solid/os.rs +++ b/library/std/src/sys/solid/os.rs @@ -1,7 +1,6 @@ use super::unsupported; -use crate::convert::TryFrom; use crate::error::Error as StdError; -use crate::ffi::{CStr, CString, OsStr, OsString}; +use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt; use crate::io; use crate::os::{ diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 37a49f2d78a..fb8d06c6682 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -332,11 +332,23 @@ pub struct FileTimes { modified: Option<SystemTime>, } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Copy, Clone, Eq, Debug)] pub struct FileType { mode: mode_t, } +impl PartialEq for FileType { + fn eq(&self, other: &Self) -> bool { + self.masked() == other.masked() + } +} + +impl core::hash::Hash for FileType { + fn hash<H: core::hash::Hasher>(&self, state: &mut H) { + self.masked().hash(state); + } +} + #[derive(Debug)] pub struct DirBuilder { mode: mode_t, @@ -548,7 +560,11 @@ impl FileType { } pub fn is(&self, mode: mode_t) -> bool { - self.mode & libc::S_IFMT == mode + self.masked() == mode + } + + fn masked(&self) -> mode_t { + self.mode & libc::S_IFMT } } diff --git a/library/std/src/sys/unix/locks/pthread_condvar.rs b/library/std/src/sys/unix/locks/pthread_condvar.rs index 1ddb09905db..6be1abc2b08 100644 --- a/library/std/src/sys/unix/locks/pthread_condvar.rs +++ b/library/std/src/sys/unix/locks/pthread_condvar.rs @@ -2,6 +2,7 @@ use crate::cell::UnsafeCell; use crate::ptr; use crate::sync::atomic::{AtomicPtr, Ordering::Relaxed}; use crate::sys::locks::{pthread_mutex, Mutex}; +use crate::sys::time::TIMESPEC_MAX; use crate::sys_common::lazy_box::{LazyBox, LazyInit}; use crate::time::Duration; @@ -12,13 +13,6 @@ pub struct Condvar { mutex: AtomicPtr<libc::pthread_mutex_t>, } -const TIMESPEC_MAX: libc::timespec = - libc::timespec { tv_sec: <libc::time_t>::MAX, tv_nsec: 1_000_000_000 - 1 }; - -fn saturating_cast_to_time_t(value: u64) -> libc::time_t { - if value > <libc::time_t>::MAX as u64 { <libc::time_t>::MAX } else { value as libc::time_t } -} - #[inline] fn raw(c: &Condvar) -> *mut libc::pthread_cond_t { c.inner.0.get() @@ -133,26 +127,15 @@ impl Condvar { target_os = "horizon" )))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { - use crate::mem; + use crate::sys::time::Timespec; let mutex = pthread_mutex::raw(mutex); self.verify(mutex); - let mut now: libc::timespec = mem::zeroed(); - let r = libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut now); - assert_eq!(r, 0); - - // Nanosecond calculations can't overflow because both values are below 1e9. - let nsec = dur.subsec_nanos() + now.tv_nsec as u32; - - let sec = saturating_cast_to_time_t(dur.as_secs()) - .checked_add((nsec / 1_000_000_000) as libc::time_t) - .and_then(|s| s.checked_add(now.tv_sec)); - let nsec = nsec % 1_000_000_000; - - let timeout = - sec.map(|s| libc::timespec { tv_sec: s, tv_nsec: nsec as _ }).unwrap_or(TIMESPEC_MAX); - + let timeout = Timespec::now(libc::CLOCK_MONOTONIC) + .checked_add_duration(&dur) + .and_then(|t| t.to_timespec()) + .unwrap_or(TIMESPEC_MAX); let r = libc::pthread_cond_timedwait(raw(self), mutex, &timeout); assert!(r == libc::ETIMEDOUT || r == 0); r == 0 @@ -169,57 +152,41 @@ impl Condvar { target_os = "espidf", target_os = "horizon" ))] - pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool { + pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { + use crate::sys::time::SystemTime; use crate::time::Instant; let mutex = pthread_mutex::raw(mutex); self.verify(mutex); - // 1000 years - let max_dur = Duration::from_secs(1000 * 365 * 86400); - - if dur > max_dur { - // OSX implementation of `pthread_cond_timedwait` is buggy - // with super long durations. When duration is greater than - // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait` - // in macOS Sierra return error 316. - // - // This program demonstrates the issue: - // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c - // - // To work around this issue, and possible bugs of other OSes, timeout - // is clamped to 1000 years, which is allowable per the API of `wait_timeout` - // because of spurious wakeups. - - dur = max_dur; - } - - // First, figure out what time it currently is, in both system and - // stable time. pthread_cond_timedwait uses system time, but we want to - // report timeout based on stable time. - let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 }; - let stable_now = Instant::now(); - let r = libc::gettimeofday(&mut sys_now, ptr::null_mut()); - assert_eq!(r, 0, "unexpected error: {:?}", crate::io::Error::last_os_error()); - - let nsec = dur.subsec_nanos() as libc::c_long + (sys_now.tv_usec * 1000) as libc::c_long; - let extra = (nsec / 1_000_000_000) as libc::time_t; - let nsec = nsec % 1_000_000_000; - let seconds = saturating_cast_to_time_t(dur.as_secs()); - - let timeout = sys_now - .tv_sec - .checked_add(extra) - .and_then(|s| s.checked_add(seconds)) - .map(|s| libc::timespec { tv_sec: s, tv_nsec: nsec }) + // OSX implementation of `pthread_cond_timedwait` is buggy + // with super long durations. When duration is greater than + // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait` + // in macOS Sierra returns error 316. + // + // This program demonstrates the issue: + // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c + // + // To work around this issue, and possible bugs of other OSes, timeout + // is clamped to 1000 years, which is allowable per the API of `wait_timeout` + // because of spurious wakeups. + let dur = Duration::min(dur, Duration::from_secs(1000 * 365 * 86400)); + + // pthread_cond_timedwait uses system time, but we want to report timeout + // based on stable time. + let now = Instant::now(); + + let timeout = SystemTime::now() + .t + .checked_add_duration(&dur) + .and_then(|t| t.to_timespec()) .unwrap_or(TIMESPEC_MAX); - // And wait! let r = libc::pthread_cond_timedwait(raw(self), mutex, &timeout); debug_assert!(r == libc::ETIMEDOUT || r == 0); // ETIMEDOUT is not a totally reliable method of determining timeout due // to clock shifts, so do the check ourselves - stable_now.elapsed() < dur + now.elapsed() < dur } } diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index c1d30dd9d52..6ecf5bdcf86 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -136,7 +136,7 @@ impl Thread { unsafe { // Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20. - let name = truncate_cstr(name, TASK_COMM_LEN); + let name = truncate_cstr::<{ TASK_COMM_LEN }>(name); let res = libc::pthread_setname_np(libc::pthread_self(), name.as_ptr()); // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked. debug_assert_eq!(res, 0); @@ -153,7 +153,7 @@ impl Thread { #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] pub fn set_name(name: &CStr) { unsafe { - let name = truncate_cstr(name, libc::MAXTHREADNAMESIZE); + let name = truncate_cstr::<{ libc::MAXTHREADNAMESIZE }>(name); let res = libc::pthread_setname_np(name.as_ptr()); // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked. debug_assert_eq!(res, 0); @@ -285,17 +285,12 @@ impl Drop for Thread { } #[cfg(any(target_os = "linux", target_os = "macos", target_os = "ios", target_os = "watchos"))] -fn truncate_cstr(cstr: &CStr, max_with_nul: usize) -> crate::borrow::Cow<'_, CStr> { - use crate::{borrow::Cow, ffi::CString}; - - if cstr.to_bytes_with_nul().len() > max_with_nul { - let bytes = cstr.to_bytes()[..max_with_nul - 1].to_vec(); - // SAFETY: the non-nul bytes came straight from a CStr. - // (CString will add the terminating nul.) - Cow::Owned(unsafe { CString::from_vec_unchecked(bytes) }) - } else { - Cow::Borrowed(cstr) +fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] { + let mut result = [0; MAX_WITH_NUL]; + for (src, dst) in cstr.to_bytes().iter().zip(&mut result[..MAX_WITH_NUL - 1]) { + *dst = *src as libc::c_char; } + result } pub fn available_parallelism() -> io::Result<NonZeroUsize> { diff --git a/library/std/src/sys/unix/thread_parker/pthread.rs b/library/std/src/sys/unix/thread_parker/pthread.rs index 3dfc0026ed1..c400c771567 100644 --- a/library/std/src/sys/unix/thread_parker/pthread.rs +++ b/library/std/src/sys/unix/thread_parker/pthread.rs @@ -6,6 +6,7 @@ use crate::pin::Pin; use crate::ptr::addr_of_mut; use crate::sync::atomic::AtomicUsize; use crate::sync::atomic::Ordering::SeqCst; +use crate::sys::time::TIMESPEC_MAX; use crate::time::Duration; const EMPTY: usize = 0; @@ -32,9 +33,6 @@ unsafe fn wait(cond: *mut libc::pthread_cond_t, lock: *mut libc::pthread_mutex_t debug_assert_eq!(r, 0); } -const TIMESPEC_MAX: libc::timespec = - libc::timespec { tv_sec: <libc::time_t>::MAX, tv_nsec: 1_000_000_000 - 1 }; - unsafe fn wait_timeout( cond: *mut libc::pthread_cond_t, lock: *mut libc::pthread_mutex_t, diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index d5abd9b581c..2daad981b73 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -5,6 +5,9 @@ pub use self::inner::Instant; const NSEC_PER_SEC: u64 = 1_000_000_000; pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() }; +#[allow(dead_code)] // Used for pthread condvar timeouts +pub const TIMESPEC_MAX: libc::timespec = + libc::timespec { tv_sec: <libc::time_t>::MAX, tv_nsec: 1_000_000_000 - 1 }; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] diff --git a/library/std/src/sys_common/thread_parker/mod.rs b/library/std/src/sys_common/thread_parker/mod.rs index f86a9a555d3..08a2bdd8229 100644 --- a/library/std/src/sys_common/thread_parker/mod.rs +++ b/library/std/src/sys_common/thread_parker/mod.rs @@ -16,6 +16,8 @@ cfg_if::cfg_if! { pub use wait_flag::Parker; } else if #[cfg(any(windows, target_family = "unix"))] { pub use crate::sys::thread_parker::Parker; + } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + pub use crate::sys::thread_parker::Parker; } else { mod generic; pub use generic::Parker; diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d8c15c76e2d..960fbdf7538 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -3,6 +3,9 @@ //! This module implements parsing `config.toml` configuration files to tweak //! how the build runs. +#[cfg(test)] +mod tests; + use std::cell::{Cell, RefCell}; use std::cmp; use std::collections::{HashMap, HashSet}; @@ -696,7 +699,7 @@ define_config! { } } -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] #[serde(untagged)] enum StringOrBool { String(String), @@ -822,6 +825,29 @@ impl Config { } pub fn parse(args: &[String]) -> Config { + #[cfg(test)] + let get_toml = |_: &_| TomlConfig::default(); + #[cfg(not(test))] + let get_toml = |file: &Path| { + let contents = + t!(fs::read_to_string(file), format!("config file {} not found", file.display())); + // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of + // TomlConfig and sub types to be monomorphized 5x by toml. + match toml::from_str(&contents) + .and_then(|table: toml::Value| TomlConfig::deserialize(table)) + { + Ok(table) => table, + Err(err) => { + eprintln!("failed to parse TOML configuration '{}': {}", file.display(), err); + crate::detail_exit(2); + } + } + }; + + Self::parse_inner(args, get_toml) + } + + fn parse_inner<'a>(args: &[String], get_toml: impl 'a + Fn(&Path) -> TomlConfig) -> Config { let flags = Flags::parse(&args); let mut config = Config::default_opts(); @@ -907,25 +933,6 @@ impl Config { config.stage0_metadata = t!(serde_json::from_slice::<Stage0Metadata>(&stage0_json)); - #[cfg(test)] - let get_toml = |_| TomlConfig::default(); - #[cfg(not(test))] - let get_toml = |file: &Path| { - let contents = - t!(fs::read_to_string(file), format!("config file {} not found", file.display())); - // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of - // TomlConfig and sub types to be monomorphized 5x by toml. - match toml::from_str(&contents) - .and_then(|table: toml::Value| TomlConfig::deserialize(table)) - { - Ok(table) => table, - Err(err) => { - eprintln!("failed to parse TOML configuration '{}': {}", file.display(), err); - crate::detail_exit(2); - } - } - }; - // Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, then `config.toml` in the root directory. let toml_path = flags .config @@ -1063,6 +1070,79 @@ impl Config { let mut optimize = None; let mut ignore_git = None; + if let Some(rust) = toml.rust { + debug = rust.debug; + debug_assertions = rust.debug_assertions; + debug_assertions_std = rust.debug_assertions_std; + overflow_checks = rust.overflow_checks; + overflow_checks_std = rust.overflow_checks_std; + debug_logging = rust.debug_logging; + debuginfo_level = rust.debuginfo_level; + debuginfo_level_rustc = rust.debuginfo_level_rustc; + debuginfo_level_std = rust.debuginfo_level_std; + debuginfo_level_tools = rust.debuginfo_level_tools; + debuginfo_level_tests = rust.debuginfo_level_tests; + config.rust_split_debuginfo = rust + .split_debuginfo + .as_deref() + .map(SplitDebuginfo::from_str) + .map(|v| v.expect("invalid value for rust.split_debuginfo")) + .unwrap_or(SplitDebuginfo::default_for_platform(&config.build.triple)); + optimize = rust.optimize; + ignore_git = rust.ignore_git; + config.rust_new_symbol_mangling = rust.new_symbol_mangling; + set(&mut config.rust_optimize_tests, rust.optimize_tests); + set(&mut config.codegen_tests, rust.codegen_tests); + set(&mut config.rust_rpath, rust.rpath); + set(&mut config.jemalloc, rust.jemalloc); + set(&mut config.test_compare_mode, rust.test_compare_mode); + set(&mut config.backtrace, rust.backtrace); + set(&mut config.channel, rust.channel); + config.description = rust.description; + set(&mut config.rust_dist_src, rust.dist_src); + set(&mut config.verbose_tests, rust.verbose_tests); + // in the case "false" is set explicitly, do not overwrite the command line args + if let Some(true) = rust.incremental { + config.incremental = true; + } + set(&mut config.use_lld, rust.use_lld); + set(&mut config.lld_enabled, rust.lld); + set(&mut config.llvm_tools_enabled, rust.llvm_tools); + config.rustc_parallel = rust.parallel_compiler.unwrap_or(false); + config.rustc_default_linker = rust.default_linker; + config.musl_root = rust.musl_root.map(PathBuf::from); + config.save_toolstates = rust.save_toolstates.map(PathBuf::from); + set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings)); + set(&mut config.backtrace_on_ice, rust.backtrace_on_ice); + set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir); + config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit; + set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo); + set(&mut config.control_flow_guard, rust.control_flow_guard); + config.llvm_libunwind_default = rust + .llvm_libunwind + .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); + + if let Some(ref backends) = rust.codegen_backends { + config.rust_codegen_backends = + backends.iter().map(|s| INTERNER.intern_str(s)).collect(); + } + + config.rust_codegen_units = rust.codegen_units.map(threads_from_config); + config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config); + config.rust_profile_use = flags.rust_profile_use.or(rust.profile_use); + config.rust_profile_generate = flags.rust_profile_generate.or(rust.profile_generate); + config.download_rustc_commit = config.download_ci_rustc_commit(rust.download_rustc); + + config.rust_lto = rust + .lto + .as_deref() + .map(|value| RustcLto::from_str(value).unwrap()) + .unwrap_or_default(); + } else { + config.rust_profile_use = flags.rust_profile_use; + config.rust_profile_generate = flags.rust_profile_generate; + } + if let Some(llvm) = toml.llvm { match llvm.ccache { Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()), @@ -1099,13 +1179,17 @@ impl Config { config.llvm_polly = llvm.polly.unwrap_or(false); config.llvm_clang = llvm.clang.unwrap_or(false); config.llvm_build_config = llvm.build_config.clone().unwrap_or(Default::default()); + + let asserts = llvm_assertions.unwrap_or(false); config.llvm_from_ci = match llvm.download_ci_llvm { Some(StringOrBool::String(s)) => { assert!(s == "if-available", "unknown option `{}` for download-ci-llvm", s); - crate::native::is_ci_llvm_available(&config, llvm_assertions.unwrap_or(false)) + crate::native::is_ci_llvm_available(&config, asserts) } Some(StringOrBool::Bool(b)) => b, - None => false, + None => { + config.channel == "dev" && crate::native::is_ci_llvm_available(&config, asserts) + } }; if config.llvm_from_ci { @@ -1145,79 +1229,9 @@ impl Config { // the link step) with each stage. config.llvm_link_shared.set(Some(true)); } - } - - if let Some(rust) = toml.rust { - debug = rust.debug; - debug_assertions = rust.debug_assertions; - debug_assertions_std = rust.debug_assertions_std; - overflow_checks = rust.overflow_checks; - overflow_checks_std = rust.overflow_checks_std; - debug_logging = rust.debug_logging; - debuginfo_level = rust.debuginfo_level; - debuginfo_level_rustc = rust.debuginfo_level_rustc; - debuginfo_level_std = rust.debuginfo_level_std; - debuginfo_level_tools = rust.debuginfo_level_tools; - debuginfo_level_tests = rust.debuginfo_level_tests; - config.rust_split_debuginfo = rust - .split_debuginfo - .as_deref() - .map(SplitDebuginfo::from_str) - .map(|v| v.expect("invalid value for rust.split_debuginfo")) - .unwrap_or(SplitDebuginfo::default_for_platform(&config.build.triple)); - optimize = rust.optimize; - ignore_git = rust.ignore_git; - config.rust_new_symbol_mangling = rust.new_symbol_mangling; - set(&mut config.rust_optimize_tests, rust.optimize_tests); - set(&mut config.codegen_tests, rust.codegen_tests); - set(&mut config.rust_rpath, rust.rpath); - set(&mut config.jemalloc, rust.jemalloc); - set(&mut config.test_compare_mode, rust.test_compare_mode); - set(&mut config.backtrace, rust.backtrace); - set(&mut config.channel, rust.channel); - config.description = rust.description; - set(&mut config.rust_dist_src, rust.dist_src); - set(&mut config.verbose_tests, rust.verbose_tests); - // in the case "false" is set explicitly, do not overwrite the command line args - if let Some(true) = rust.incremental { - config.incremental = true; - } - set(&mut config.use_lld, rust.use_lld); - set(&mut config.lld_enabled, rust.lld); - set(&mut config.llvm_tools_enabled, rust.llvm_tools); - config.rustc_parallel = rust.parallel_compiler.unwrap_or(false); - config.rustc_default_linker = rust.default_linker; - config.musl_root = rust.musl_root.map(PathBuf::from); - config.save_toolstates = rust.save_toolstates.map(PathBuf::from); - set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings)); - set(&mut config.backtrace_on_ice, rust.backtrace_on_ice); - set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir); - config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit; - set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo); - set(&mut config.control_flow_guard, rust.control_flow_guard); - config.llvm_libunwind_default = rust - .llvm_libunwind - .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); - - if let Some(ref backends) = rust.codegen_backends { - config.rust_codegen_backends = - backends.iter().map(|s| INTERNER.intern_str(s)).collect(); - } - - config.rust_codegen_units = rust.codegen_units.map(threads_from_config); - config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config); - config.rust_profile_use = flags.rust_profile_use.or(rust.profile_use); - config.rust_profile_generate = flags.rust_profile_generate.or(rust.profile_generate); - config.download_rustc_commit = config.download_ci_rustc_commit(rust.download_rustc); - - config.rust_lto = rust - .lto - .as_deref() - .map(|value| RustcLto::from_str(value).unwrap()) - .unwrap_or_default(); } else { - config.rust_profile_use = flags.rust_profile_use; - config.rust_profile_generate = flags.rust_profile_generate; + config.llvm_from_ci = + config.channel == "dev" && crate::native::is_ci_llvm_available(&config, false); } if let Some(t) = toml.target { diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs new file mode 100644 index 00000000000..c30c9131745 --- /dev/null +++ b/src/bootstrap/config/tests.rs @@ -0,0 +1,24 @@ +use super::{Config, TomlConfig}; +use std::path::Path; + +fn toml(config: &str) -> impl '_ + Fn(&Path) -> TomlConfig { + |&_| toml::from_str(config).unwrap() +} + +fn parse(config: &str) -> Config { + Config::parse_inner(&["check".to_owned(), "--config=/does/not/exist".to_owned()], toml(config)) +} + +#[test] +fn download_ci_llvm() { + let parse_llvm = |s| parse(s).llvm_from_ci; + let if_available = parse_llvm("llvm.download-ci-llvm = \"if-available\""); + + assert!(parse_llvm("llvm.download-ci-llvm = true")); + assert!(!parse_llvm("llvm.download-ci-llvm = false")); + assert_eq!(parse_llvm(""), if_available); + assert_eq!(parse_llvm("rust.channel = \"dev\""), if_available); + assert!(!parse_llvm("rust.channel = \"stable\"")); +} + +// FIXME: add test for detecting `src` and `out` diff --git a/src/bootstrap/defaults/config.user.toml b/src/bootstrap/defaults/config.user.toml index 6647061d88f..48ae2fe448d 100644 --- a/src/bootstrap/defaults/config.user.toml +++ b/src/bootstrap/defaults/config.user.toml @@ -7,3 +7,7 @@ test-stage = 2 doc-stage = 2 # When compiling from source, you usually want all tools. extended = true + +[llvm] +# Most users installing from source want to build all parts of the project from source, not just rustc itself. +download-ci-llvm = false diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 3ed53452309..570fe6484e3 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1639,10 +1639,10 @@ fn chmod(_path: &Path, _perms: u32) {} /// If the test is running and code is an error code, it will cause a panic. fn detail_exit(code: i32) -> ! { // if in test and code is an error code, panic with status code provided - if cfg!(test) && code != 0 { + if cfg!(test) { panic!("status code: {}", code); } else { - //otherwise,exit with provided status code + // otherwise,exit with provided status code std::process::exit(code); } } diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile index 9a290edd561..6b7b32a8bc7 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile @@ -24,5 +24,5 @@ ENV \ ENV HOSTS=powerpc64le-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs +ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile index c3b47c3510d..06f15bd1211 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile @@ -25,7 +25,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ zlib1g-dev \ xz-utils \ nodejs \ - + \ # Install powershell so we can test x.ps1 on Linux apt-transport-https software-properties-common && \ curl -s "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" > packages-microsoft-prod.deb && \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile index 501d2781646..58c0c5db1a5 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile @@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ sudo \ xz-utils \ tidy \ - + \ # Install dependencies for chromium browser gconf-service \ libasound2 \ diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index b33405f18e9..9bbf9e28fff 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -14,6 +14,9 @@ This feature allows for use of one of following sanitizers: forward-edge control flow protection. * [HWAddressSanitizer](#hwaddresssanitizer) a memory error detector similar to AddressSanitizer, but based on partial hardware assistance. +* [KernelControlFlowIntegrity](#kernelcontrolflowintegrity) LLVM Kernel Control + Flow Integrity (KCFI) provides forward-edge control flow protection for + operating systems kernels. * [LeakSanitizer](#leaksanitizer) a run-time memory leak detector. * [MemorySanitizer](#memorysanitizer) a detector of uninitialized reads. * [MemTagSanitizer](#memtagsanitizer) fast memory error detector based on @@ -502,6 +505,32 @@ Registers where the failure occurred (pc 0xaaaae0ae4a98): SUMMARY: HWAddressSanitizer: tag-mismatch (/.../main+0x54a94) ``` +# KernelControlFlowIntegrity + +The LLVM Kernel Control Flow Integrity (CFI) support to the Rust compiler +initially provides forward-edge control flow protection for operating systems +kernels for Rust-compiled code only by aggregating function pointers in groups +identified by their return and parameter types. (See [LLVM commit cff5bef "KCFI +sanitizer"](https://github.com/llvm/llvm-project/commit/cff5bef948c91e4919de8a5fb9765e0edc13f3de).) + +Forward-edge control flow protection for C or C++ and Rust -compiled code "mixed +binaries" (i.e., for when C or C++ and Rust -compiled code share the same +virtual address space) will be provided in later work by defining and using +compatible type identifiers (see Type metadata in the design document in the +tracking issue [#89653](https://github.com/rust-lang/rust/issues/89653)). + +LLVM KCFI can be enabled with `-Zsanitizer=kcfi`. + +LLVM KCFI is supported on the following targets: + +* `aarch64-linux-android` +* `aarch64-unknown-linux-gnu` +* `x86_64-linux-android` +* `x86_64-unknown-linux-gnu` + +See the [Clang KernelControlFlowIntegrity documentation][clang-kcfi] for more +details. + # LeakSanitizer LeakSanitizer is run-time memory leak detector. @@ -693,6 +722,7 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT [clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html [clang-cfi]: https://clang.llvm.org/docs/ControlFlowIntegrity.html [clang-hwasan]: https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html +[clang-kcfi]: https://clang.llvm.org/docs/ControlFlowIntegrity.html#fsanitize-kcfi [clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html [clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html [clang-scs]: https://clang.llvm.org/docs/ShadowCallStack.html diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e0cdb86d9d1..56b40d8c66b 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -69,6 +69,8 @@ pub(crate) struct Options { pub(crate) input: PathBuf, /// The name of the crate being documented. pub(crate) crate_name: Option<String>, + /// Whether or not this is a bin crate + pub(crate) bin_crate: bool, /// Whether or not this is a proc-macro crate pub(crate) proc_macro_crate: bool, /// How to format errors and warnings. @@ -176,6 +178,7 @@ impl fmt::Debug for Options { f.debug_struct("Options") .field("input", &self.input) .field("crate_name", &self.crate_name) + .field("bin_crate", &self.bin_crate) .field("proc_macro_crate", &self.proc_macro_crate) .field("error_format", &self.error_format) .field("libs", &self.libs) @@ -667,6 +670,7 @@ impl Options { None => OutputFormat::default(), }; let crate_name = matches.opt_str("crate-name"); + let bin_crate = crate_types.contains(&CrateType::Executable); let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro); let playground_url = matches.opt_str("playground-url"); let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); @@ -718,6 +722,7 @@ impl Options { rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); let options = Options { input, + bin_crate, proc_macro_crate, error_format, diagnostic_width, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 08f8096b07b..36d15ec3b86 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2957,14 +2957,23 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite // The call locations are output in sequence, so that sequence needs to be determined. // Ideally the most "relevant" examples would be shown first, but there's no general algorithm - // for determining relevance. Instead, we prefer the smallest examples being likely the easiest to - // understand at a glance. + // for determining relevance. We instead proxy relevance with the following heuristics: + // 1. Code written to be an example is better than code not written to be an example, e.g. + // a snippet from examples/foo.rs is better than src/lib.rs. We don't know the Cargo + // directory structure in Rustdoc, so we proxy this by prioritizing code that comes from + // a --crate-type bin. + // 2. Smaller examples are better than large examples. So we prioritize snippets that have + // the smallest number of lines in their enclosing item. + // 3. Finally we sort by the displayed file name, which is arbitrary but prevents the + // ordering of examples from randomly changing between Rustdoc invocations. let ordered_locations = { - let sort_criterion = |(_, call_data): &(_, &CallData)| { + fn sort_criterion<'a>( + (_, call_data): &(&PathBuf, &'a CallData), + ) -> (bool, u32, &'a String) { // Use the first location because that's what the user will see initially let (lo, hi) = call_data.locations[0].enclosing_item.byte_span; - hi - lo - }; + (!call_data.is_bin, hi - lo, &call_data.display_name) + } let mut locs = call_locations.iter().collect::<Vec<_>>(); locs.sort_by_key(sort_criterion); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 11136179607..91162ca4892 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -212,7 +212,7 @@ pre.rust a, .mobile-topbar h2 a, h1 a, .search-results a, -.item-left .stab, +.stab, .result-name .primitive > i, .result-name .keyword > i { color: var(--main-color); } @@ -630,22 +630,16 @@ pre, .rustdoc.source .example-wrap { .docblock table { margin: .5em 0; - width: calc(100% - 2px); - overflow-x: auto; - display: block; border-collapse: collapse; } -.docblock table td { +.docblock table td, .docblock table th { padding: .5em; - border: 1px dashed var(--border-color); - vertical-align: top; + border: 1px solid var(--border-color); } -.docblock table th { - padding: .5em; - text-align: left; - border: 1px solid var(--border-color); +.docblock table tbody tr:nth-child(2n) { + background: var(--table-alt-row-background-color); } /* Shift "where ..." part of method or fn definition down a line */ @@ -966,22 +960,29 @@ so that we can apply CSS-filters to change the arrow color in themes */ } .item-info .stab { - width: fit-content; /* This min-height is needed to unify the height of the stab elements because some of them have emojis. */ min-height: 36px; display: flex; - align-items: center; - white-space: pre-wrap; -} -.stab { padding: 3px; margin-bottom: 5px; +} +.item-left .stab { + margin-left: 0.3125em; +} +.stab { + padding: 0 2px; font-size: 0.875rem; font-weight: normal; color: var(--main-color); background-color: var(--stab-background-color); + width: fit-content; + align-items: center; + white-space: pre-wrap; + border-radius: 3px; + display: inline-flex; + vertical-align: text-bottom; } .stab.portability > code { @@ -994,12 +995,6 @@ so that we can apply CSS-filters to change the arrow color in themes */ margin-right: 0.3rem; } -/* This is to prevent the `.stab` elements to overflow the .docblock elements. */ -.docblock .stab { - padding: 0 0.125em; - margin-bottom: 0; -} - /* Black one-pixel outline around emoji shapes */ .emoji { text-shadow: @@ -1009,16 +1004,6 @@ so that we can apply CSS-filters to change the arrow color in themes */ 0 -1px 0 black; } -.item-left .stab { - border-radius: 3px; - display: inline-block; - line-height: 1.2; - margin-bottom: 0; - margin-left: 0.3125em; - padding: 2px; - vertical-align: text-bottom; -} - .module-item.unstable, .import-item.unstable { opacity: 0.65; @@ -1748,7 +1733,6 @@ in storage.js top: 100px; width: 30px; font-size: 1.5rem; - text-align: center; padding: 0; z-index: 10; border-top-right-radius: 3px; @@ -1813,6 +1797,22 @@ in storage.js } } +/* Should have min-width: (N + 1)px where N is the mobile breakpoint above. */ +@media (min-width: 701px) { + /* Places file-link for a scraped example on top of the example to save space. + We only do this on large screens so the file-link doesn't overlap too much + with the example's content. */ + .scraped-example-title { + position: absolute; + z-index: 10; + background: var(--main-background-color); + bottom: 8px; + right: 5px; + padding: 2px 4px; + box-shadow: 0 0 4px var(--main-background-color); + } +} + @media print { nav.sidebar, nav.sub, .out-of-band, a.srclink, #copy-path, details.rustdoc-toggle[open] > summary::before, details.rustdoc-toggle > summary::before, @@ -1899,6 +1899,11 @@ in storage.js border-radius: 50px; } +.scraped-example { + /* So .scraped-example-title can be positioned absolutely */ + position: relative; +} + .scraped-example .code-wrapper { position: relative; display: flex; @@ -1908,18 +1913,30 @@ in storage.js } .scraped-example:not(.expanded) .code-wrapper { - max-height: 240px; + /* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number + * of lines shown in the un-expanded example code viewer. This pre needs to have + * a max-height equal to line-height * N. The line-height is currently 1.5em, + * and we include additional 10px for padding. */ + max-height: calc(1.5em * 5 + 10px); } .scraped-example:not(.expanded) .code-wrapper pre { overflow-y: hidden; - max-height: 240px; padding-bottom: 0; + /* See above comment, should be the same max-height. */ + max-height: calc(1.5em * 5 + 10px); +} + +.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper, +.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre { + /* See above comment, except this height is based on HIDDEN_MAX_LINES. */ + max-height: calc(1.5em * 10 + 10px); } .scraped-example .code-wrapper .next, .scraped-example .code-wrapper .prev, .scraped-example .code-wrapper .expand { + color: var(--main-color); position: absolute; top: 0.25em; z-index: 1; diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 6e0905e730d..eba845bf5a9 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -87,6 +87,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) --crate-search-hover-border: #e0e0e0; --source-sidebar-background-selected: #14191f; --source-sidebar-background-hover: #14191f; + --table-alt-row-background-color: #191f26; } h1, h2, h3, h4 { @@ -159,11 +160,6 @@ body.source .example-wrap pre.rust a { background: #333; } -.module-item .stab, -.import-item .stab { - color: #000; -} - .result-name .primitive > i, .result-name .keyword > i { color: #788797; } diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 334fc3de561..d945e956c53 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -82,6 +82,7 @@ --crate-search-hover-border: #2196f3; --source-sidebar-background-selected: #333; --source-sidebar-background-hover: #444; + --table-alt-row-background-color: #2A2A2A; } .content .item-info::before { color: #ccc; } diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 453e7508af4..58955a79316 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -79,6 +79,7 @@ --crate-search-hover-border: #717171; --source-sidebar-background-selected: #fff; --source-sidebar-background-hover: #e0e0e0; + --table-alt-row-background-color: #F5F5F5; } .content .item-info::before { color: #ccc; } diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 623f46b1096..152116089c7 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -622,7 +622,7 @@ function loadCss(cssUrl) { const innerToggle = document.getElementById(toggleAllDocsId); removeClass(innerToggle, "will-expand"); onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { - if (!hasClass(e, "type-contents-toggle")) { + if (!hasClass(e, "type-contents-toggle") && !hasClass(e, "more-examples-toggle")) { e.open = true; } }); diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js index e328e656edd..7a3a9c5f340 100644 --- a/src/librustdoc/html/static/js/scrape-examples.js +++ b/src/librustdoc/html/static/js/scrape-examples.js @@ -3,25 +3,33 @@ "use strict"; (function() { - // Number of lines shown when code viewer is not expanded - const MAX_LINES = 10; + // Number of lines shown when code viewer is not expanded. + // DEFAULT is the first example shown by default, while HIDDEN is + // the examples hidden beneath the "More examples" toggle. + // + // NOTE: these values MUST be synchronized with certain rules in rustdoc.css! + const DEFAULT_MAX_LINES = 5; + const HIDDEN_MAX_LINES = 10; // Scroll code block to the given code location - function scrollToLoc(elt, loc) { + function scrollToLoc(elt, loc, isHidden) { const lines = elt.querySelector(".src-line-numbers"); let scrollOffset; // If the block is greater than the size of the viewer, // then scroll to the top of the block. Otherwise scroll // to the middle of the block. - if (loc[1] - loc[0] > MAX_LINES) { + const maxLines = isHidden ? HIDDEN_MAX_LINES : DEFAULT_MAX_LINES; + if (loc[1] - loc[0] > maxLines) { const line = Math.max(0, loc[0] - 1); scrollOffset = lines.children[line].offsetTop; } else { const wrapper = elt.querySelector(".code-wrapper"); const halfHeight = wrapper.offsetHeight / 2; - const offsetMid = (lines.children[loc[0]].offsetTop - + lines.children[loc[1]].offsetTop) / 2; + const offsetTop = lines.children[loc[0]].offsetTop; + const lastLine = lines.children[loc[1]]; + const offsetBot = lastLine.offsetTop + lastLine.offsetHeight; + const offsetMid = (offsetTop + offsetBot) / 2; scrollOffset = offsetMid - halfHeight; } @@ -29,7 +37,7 @@ elt.querySelector(".rust").scrollTo(0, scrollOffset); } - function updateScrapedExample(example) { + function updateScrapedExample(example, isHidden) { const locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent); let locIndex = 0; const highlights = Array.prototype.slice.call(example.querySelectorAll(".highlight")); @@ -40,7 +48,7 @@ const onChangeLoc = changeIndex => { removeClass(highlights[locIndex], "focus"); changeIndex(); - scrollToLoc(example, locs[locIndex][0]); + scrollToLoc(example, locs[locIndex][0], isHidden); addClass(highlights[locIndex], "focus"); const url = locs[locIndex][1]; @@ -70,7 +78,7 @@ expandButton.addEventListener("click", () => { if (hasClass(example, "expanded")) { removeClass(example, "expanded"); - scrollToLoc(example, locs[0][0]); + scrollToLoc(example, locs[0][0], isHidden); } else { addClass(example, "expanded"); } @@ -78,11 +86,11 @@ } // Start with the first example in view - scrollToLoc(example, locs[0][0]); + scrollToLoc(example, locs[0][0], isHidden); } const firstExamples = document.querySelectorAll(".scraped-example-list > .scraped-example"); - onEachLazy(firstExamples, updateScrapedExample); + onEachLazy(firstExamples, el => updateScrapedExample(el, false)); onEachLazy(document.querySelectorAll(".more-examples-toggle"), toggle => { // Allow users to click the left border of the <details> section to close it, // since the section can be large and finding the [+] button is annoying. @@ -99,7 +107,7 @@ // depends on offsetHeight, a property that requires an element to be visible to // compute correctly. setTimeout(() => { - onEachLazy(moreExamples, updateScrapedExample); + onEachLazy(moreExamples, el => updateScrapedExample(el, true)); }); }, {once: true}); }); diff --git a/src/librustdoc/html/static/scrape-examples-help.md b/src/librustdoc/html/static/scrape-examples-help.md index 035b2e18b00..002d19ec9b6 100644 --- a/src/librustdoc/html/static/scrape-examples-help.md +++ b/src/librustdoc/html/static/scrape-examples-help.md @@ -1,4 +1,4 @@ -Rustdoc will automatically scrape examples of documented items from the `examples/` directory of a project. These examples will be included within the generated documentation for that item. For example, if your library contains a public function: +Rustdoc will automatically scrape examples of documented items from a project's source code. These examples will be included within the generated documentation for that item. For example, if your library contains a public function: ```rust // src/lib.rs @@ -16,6 +16,7 @@ fn main() { Then this code snippet will be included in the documentation for `a_func`. + ## How to read scraped examples Scraped examples are shown as blocks of code from a given file. The relevant item will be highlighted. If the file is larger than a couple lines, only a small window will be shown which you can expand by clicking ↕ in the top-right. If a file contains multiple instances of an item, you can use the ≺ and ≻ buttons to toggle through each instance. @@ -25,7 +26,7 @@ If there is more than one file that contains examples, then you should click "Mo ## How Rustdoc scrapes examples -When you run `cargo doc`, Rustdoc will analyze all the crates that match Cargo's `--examples` filter for instances of items that occur in the crates being documented. Then Rustdoc will include the source code of these instances in the generated documentation. +When you run `cargo doc -Zunstable-options -Zrustdoc-scrape-examples`, Rustdoc will analyze all the documented crates for uses of documented items. Then Rustdoc will include the source code of these instances in the generated documentation. Rustdoc has a few techniques to ensure this doesn't overwhelm documentation readers, and that it doesn't blow up the page size: diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 6d34f484754..ef1d7da5a34 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -674,7 +674,7 @@ type MainResult = Result<(), ErrorGuaranteed>; fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainResult { match res { - Ok(()) => Ok(()), + Ok(()) => diag.has_errors().map_or(Ok(()), Err), Err(err) => { let reported = diag.struct_err(&err).emit(); Err(reported) @@ -689,7 +689,7 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( tcx: TyCtxt<'tcx>, ) -> MainResult { match formats::run_format::<T>(krate, renderopts, cache, tcx) { - Ok(_) => Ok(()), + Ok(_) => tcx.sess.has_errors().map_or(Ok(()), Err), Err(e) => { let mut msg = tcx.sess.struct_err(&format!("couldn't generate documentation: {}", e.error)); @@ -774,6 +774,7 @@ fn main_args(at_args: &[String]) -> MainResult { let output_format = options.output_format; let externs = options.externs.clone(); let scrape_examples_options = options.scrape_examples_options.clone(); + let bin_crate = options.bin_crate; let config = core::create_config(options); @@ -832,7 +833,14 @@ fn main_args(at_args: &[String]) -> MainResult { info!("finished with rustc"); if let Some(options) = scrape_examples_options { - return scrape_examples::run(krate, render_opts, cache, tcx, options); + return scrape_examples::run( + krate, + render_opts, + cache, + tcx, + options, + bin_crate, + ); } cache.crate_version = crate_version; diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index dfa6ba38b88..f2ee99cd9d4 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -110,6 +110,7 @@ pub(crate) struct CallData { pub(crate) url: String, pub(crate) display_name: String, pub(crate) edition: Edition, + pub(crate) is_bin: bool, } pub(crate) type FnCallLocations = FxHashMap<PathBuf, CallData>; @@ -122,6 +123,7 @@ struct FindCalls<'a, 'tcx> { cx: Context<'tcx>, target_crates: Vec<CrateNum>, calls: &'a mut AllCallLocations, + bin_crate: bool, } impl<'a, 'tcx> Visitor<'tcx> for FindCalls<'a, 'tcx> @@ -245,7 +247,9 @@ where let mk_call_data = || { let display_name = file_path.display().to_string(); let edition = call_span.edition(); - CallData { locations: Vec::new(), url, display_name, edition } + let is_bin = self.bin_crate; + + CallData { locations: Vec::new(), url, display_name, edition, is_bin } }; let fn_key = tcx.def_path_hash(*def_id); @@ -274,6 +278,7 @@ pub(crate) fn run( cache: formats::cache::Cache, tcx: TyCtxt<'_>, options: ScrapeExamplesOptions, + bin_crate: bool, ) -> interface::Result<()> { let inner = move || -> Result<(), String> { // Generates source files for examples @@ -300,7 +305,8 @@ pub(crate) fn run( // Run call-finder on all items let mut calls = FxHashMap::default(); - let mut finder = FindCalls { calls: &mut calls, tcx, map: tcx.hir(), cx, target_crates }; + let mut finder = + FindCalls { calls: &mut calls, tcx, map: tcx.hir(), cx, target_crates, bin_crate }; tcx.hir().visit_all_item_likes_in_crate(&mut finder); // The visitor might have found a type error, which we need to diff --git a/src/test/codegen/catch-unwind.rs b/src/test/codegen/catch-unwind.rs index 3ea3a24bfae..b90ef104ce7 100644 --- a/src/test/codegen/catch-unwind.rs +++ b/src/test/codegen/catch-unwind.rs @@ -8,6 +8,8 @@ // On riscv the closure is another function, placed before fn foo so CHECK can't // find it // ignore-riscv64 FIXME +// On s390x the closure is also in another function +// ignore-s390x FIXME #![crate_type = "lib"] #![feature(c_unwind)] diff --git a/src/test/codegen/issue-105386-ub-in-debuginfo.rs b/src/test/codegen/issue-105386-ub-in-debuginfo.rs new file mode 100644 index 00000000000..d54ac9e33bc --- /dev/null +++ b/src/test/codegen/issue-105386-ub-in-debuginfo.rs @@ -0,0 +1,22 @@ +// compile-flags: --crate-type=lib -O -Cdebuginfo=2 -Cno-prepopulate-passes +// min-llvm-version: 15.0 # this test uses opaque pointer notation +#![feature(stmt_expr_attributes)] + +pub struct S([usize; 8]); + +#[no_mangle] +pub fn outer_function(x: S, y: S) -> usize { + (#[inline(always)]|| { + let _z = x; + y.0[0] + })() +} + +// Check that we do not attempt to load from the spilled arg before it is assigned to +// when generating debuginfo. +// CHECK-LABEL: @outer_function +// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:9:23: 9:25]" +// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:9:23: 9:25]", ptr [[spill]] +// CHECK-NOT: [[load:%.*]] = load ptr, ptr +// CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]]) +// CHECK: call void @llvm.memcpy{{.*}}(ptr {{align .*}} [[spill]], ptr {{align .*}} %x diff --git a/src/test/codegen/remap_path_prefix/main.rs b/src/test/codegen/remap_path_prefix/main.rs index 9bef743ddcb..78ebbccfce1 100644 --- a/src/test/codegen/remap_path_prefix/main.rs +++ b/src/test/codegen/remap_path_prefix/main.rs @@ -12,7 +12,7 @@ mod aux_mod; include!("aux_mod.rs"); // Here we check that the expansion of the file!() macro is mapped. -// CHECK: @alloc2 = private unnamed_addr constant <{ [34 x i8] }> <{ [34 x i8] c"/the/src/remap_path_prefix/main.rs" }>, align 1 +// CHECK: @alloc2 = private unnamed_addr constant <{ [34 x i8] }> <{ [34 x i8] c"/the/src/remap_path_prefix/main.rs" }> pub static FILE_PATH: &'static str = file!(); fn main() { diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs index 9d18c5f03c6..f733de12b35 100644 --- a/src/test/codegen/repr-transparent-aggregates-1.rs +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -8,6 +8,7 @@ // ignore-powerpc // ignore-powerpc64 // ignore-riscv64 see codegen/riscv-abi +// ignore-s390x // ignore-windows // See repr-transparent.rs diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs index c68ba8460cb..4f2313ce47a 100644 --- a/src/test/codegen/repr-transparent.rs +++ b/src/test/codegen/repr-transparent.rs @@ -2,6 +2,7 @@ // ignore-riscv64 riscv64 has an i128 type used with test_Vector // see codegen/riscv-abi for riscv functiona call tests +// ignore-s390x s390x with default march passes vector types per reference #![crate_type="lib"] #![feature(repr_simd, transparent_unions)] diff --git a/src/test/codegen/sanitizer-kcfi-add-kcfi-flag.rs b/src/test/codegen/sanitizer-kcfi-add-kcfi-flag.rs new file mode 100644 index 00000000000..c2eb852aec3 --- /dev/null +++ b/src/test/codegen/sanitizer-kcfi-add-kcfi-flag.rs @@ -0,0 +1,11 @@ +// Verifies that "kcfi" module flag is added. +// +// needs-sanitizer-kcfi +// compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi + +#![crate_type="lib"] + +pub fn foo() { +} + +// CHECK: !{{[0-9]+}} = !{i32 4, !"kcfi", i32 1} diff --git a/src/test/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs b/src/test/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs new file mode 100644 index 00000000000..0afd9727517 --- /dev/null +++ b/src/test/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs @@ -0,0 +1,47 @@ +// Verifies that KCFI type metadata for functions are emitted. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: +// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi + +#![crate_type="lib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } + +impl Copy for i32 {} + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // FIXME(rcvalle): Change <unknown kind #36> to !kcfi_type when Rust is updated to LLVM 16 + // CHECK-SAME: {{.*}}!<unknown kind #36> ![[TYPE1:[0-9]+]] + // CHECK: call i32 %f(i32 %arg){{.*}}[ "kcfi"(i32 -1666898348) ] + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // FIXME(rcvalle): Change <unknown kind #36> to !kcfi_type when Rust is updated to LLVM 16 + // CHECK-SAME: {{.*}}!<unknown kind #36> ![[TYPE2:[0-9]+]] + // CHECK: call i32 %f(i32 %arg1, i32 %arg2){{.*}}[ "kcfi"(i32 -1789026986) ] + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // FIXME(rcvalle): Change <unknown kind #36> to !kcfi_type when Rust is updated to LLVM 16 + // CHECK-SAME: {{.*}}!<unknown kind #36> ![[TYPE3:[0-9]+]] + // CHECK: call i32 %f(i32 %arg1, i32 %arg2, i32 %arg3){{.*}}[ "kcfi"(i32 1248878270) ] + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i32 653723426} +// CHECK: ![[TYPE2]] = !{i32 412174924} +// CHECK: ![[TYPE3]] = !{i32 -636668840} diff --git a/src/test/codegen/uninit-consts.rs b/src/test/codegen/uninit-consts.rs index 4c07740b356..98a6761f8ab 100644 --- a/src/test/codegen/uninit-consts.rs +++ b/src/test/codegen/uninit-consts.rs @@ -14,7 +14,7 @@ pub struct PartiallyUninit { // CHECK: [[FULLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [10 x i8] }> undef -// CHECK: [[PARTIALLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [4 x i8], [12 x i8] }> <{ [4 x i8] c"\EF\BE\AD\DE", [12 x i8] undef }>, align 4 +// CHECK: [[PARTIALLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [4 x i8], [12 x i8] }> <{ [4 x i8] c"{{\\EF\\BE\\AD\\DE|\\DE\\AD\\BE\\EF}}", [12 x i8] undef }>, align 4 // This shouldn't contain undef, since it contains more chunks // than the default value of uninit_const_chunk_threshold. diff --git a/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff b/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff index 57e298625f9..9780332d8bf 100644 --- a/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff +++ b/src/test/mir-opt/76803_regression.encode.SimplifyBranchSame.diff @@ -8,7 +8,7 @@ bb0: { _2 = discriminant(_1); // scope 0 at $DIR/76803_regression.rs:+1:11: +1:12 - switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/76803_regression.rs:+1:5: +1:12 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/76803_regression.rs:+1:5: +1:12 } bb1: { diff --git a/src/test/mir-opt/bool_compare.opt1.InstCombine.diff b/src/test/mir-opt/bool_compare.opt1.InstCombine.diff index 9c5a9fa9abb..0af5d82d315 100644 --- a/src/test/mir-opt/bool_compare.opt1.InstCombine.diff +++ b/src/test/mir-opt/bool_compare.opt1.InstCombine.diff @@ -14,7 +14,7 @@ - _2 = Ne(move _3, const true); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 } bb1: { diff --git a/src/test/mir-opt/bool_compare.opt2.InstCombine.diff b/src/test/mir-opt/bool_compare.opt2.InstCombine.diff index 58c52c4b7d7..f5d1febd991 100644 --- a/src/test/mir-opt/bool_compare.opt2.InstCombine.diff +++ b/src/test/mir-opt/bool_compare.opt2.InstCombine.diff @@ -14,7 +14,7 @@ - _2 = Ne(const true, move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:16: +1:17 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:17 } bb1: { diff --git a/src/test/mir-opt/bool_compare.opt3.InstCombine.diff b/src/test/mir-opt/bool_compare.opt3.InstCombine.diff index 676428c95c1..e7432adac7d 100644 --- a/src/test/mir-opt/bool_compare.opt3.InstCombine.diff +++ b/src/test/mir-opt/bool_compare.opt3.InstCombine.diff @@ -14,7 +14,7 @@ - _2 = Eq(move _3, const false); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 } bb1: { diff --git a/src/test/mir-opt/bool_compare.opt4.InstCombine.diff b/src/test/mir-opt/bool_compare.opt4.InstCombine.diff index addfcd769a5..6b3e27772f7 100644 --- a/src/test/mir-opt/bool_compare.opt4.InstCombine.diff +++ b/src/test/mir-opt/bool_compare.opt4.InstCombine.diff @@ -14,7 +14,7 @@ - _2 = Eq(const false, move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + _2 = Not(move _3); // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 StorageDead(_3); // scope 0 at $DIR/bool_compare.rs:+1:17: +1:18 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/bool_compare.rs:+1:8: +1:18 } bb1: { diff --git a/src/test/mir-opt/building/issue_101867.main.built.after.mir b/src/test/mir-opt/building/issue_101867.main.built.after.mir index 0ebd840cf2d..628a33f1020 100644 --- a/src/test/mir-opt/building/issue_101867.main.built.after.mir +++ b/src/test/mir-opt/building/issue_101867.main.built.after.mir @@ -27,7 +27,7 @@ fn main() -> () { StorageLive(_5); // scope 1 at $DIR/issue_101867.rs:+2:14: +2:15 FakeRead(ForMatchedPlace(None), _1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20 _6 = discriminant(_1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20 - switchInt(move _6) -> [1_isize: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16 + switchInt(move _6) -> [1: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16 } bb1: { diff --git a/src/test/mir-opt/building/issue_49232.main.built.after.mir b/src/test/mir-opt/building/issue_49232.main.built.after.mir index 9182bcaa21f..de5e4c0f6ed 100644 --- a/src/test/mir-opt/building/issue_49232.main.built.after.mir +++ b/src/test/mir-opt/building/issue_49232.main.built.after.mir @@ -25,7 +25,7 @@ fn main() -> () { StorageLive(_3); // scope 0 at $DIR/issue_49232.rs:+3:19: +3:23 _3 = const true; // scope 0 at $DIR/issue_49232.rs:+3:19: +3:23 FakeRead(ForMatchedPlace(None), _3); // scope 0 at $DIR/issue_49232.rs:+3:19: +3:23 - switchInt(_3) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/issue_49232.rs:+3:13: +3:23 + switchInt(_3) -> [0: bb3, otherwise: bb4]; // scope 0 at $DIR/issue_49232.rs:+3:13: +3:23 } bb3: { diff --git a/src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir b/src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir index 9a190c3d60e..cb36bc64da6 100644 --- a/src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir +++ b/src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir @@ -28,7 +28,7 @@ fn full_tested_match() -> () { _2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 - switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27 + switchInt(move _3) -> [0: bb1, 1: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27 } bb1: { @@ -60,7 +60,7 @@ fn full_tested_match() -> () { } bb6: { - switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + switchInt(move _7) -> [0: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 } bb7: { diff --git a/src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir b/src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir index 1c9953e7efc..7f8755faac6 100644 --- a/src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir +++ b/src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir @@ -28,7 +28,7 @@ fn full_tested_match2() -> () { _2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27 - switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27 + switchInt(move _3) -> [0: bb1, 1: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:27 } bb1: { @@ -66,7 +66,7 @@ fn full_tested_match2() -> () { } bb6: { - switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 + switchInt(move _7) -> [0: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27 } bb7: { diff --git a/src/test/mir-opt/building/match_false_edges.main.built.after.mir b/src/test/mir-opt/building/match_false_edges.main.built.after.mir index 08c67d39d78..e8b93f4371e 100644 --- a/src/test/mir-opt/building/match_false_edges.main.built.after.mir +++ b/src/test/mir-opt/building/match_false_edges.main.built.after.mir @@ -39,7 +39,7 @@ fn main() -> () { _2 = Option::<i32>::Some(const 1_i32); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 _4 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 - switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26 + switchInt(move _4) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26 } bb1: { @@ -56,7 +56,7 @@ fn main() -> () { bb4: { _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26 - switchInt(move _3) -> [1_isize: bb6, otherwise: bb5]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26 + switchInt(move _3) -> [1: bb6, otherwise: bb5]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26 } bb5: { @@ -87,7 +87,7 @@ fn main() -> () { } bb9: { - switchInt(move _8) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 + switchInt(move _8) -> [0: bb11, otherwise: bb10]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28 } bb10: { @@ -134,7 +134,7 @@ fn main() -> () { } bb15: { - switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 + switchInt(move _12) -> [0: bb17, otherwise: bb16]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29 } bb16: { diff --git a/src/test/mir-opt/building/simple_match.match_bool.built.after.mir b/src/test/mir-opt/building/simple_match.match_bool.built.after.mir index a4516026c3b..aa2fd46320e 100644 --- a/src/test/mir-opt/building/simple_match.match_bool.built.after.mir +++ b/src/test/mir-opt/building/simple_match.match_bool.built.after.mir @@ -6,7 +6,7 @@ fn match_bool(_1: bool) -> usize { bb0: { FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple_match.rs:+1:11: +1:12 - switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple_match.rs:+1:5: +1:12 + switchInt(_1) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/simple_match.rs:+1:5: +1:12 } bb1: { diff --git a/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff b/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff index fade2d0bc6e..a717d1bbd12 100644 --- a/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff +++ b/src/test/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff @@ -11,9 +11,9 @@ bb0: { - StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _3 = discriminant(_1); // scope 0 at $DIR/const_goto.rs:+1:17: +1:20 -- switchInt(move _3) -> [1_isize: bb2, 2_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- switchInt(move _3) -> [1: bb2, 2: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _2 = discriminant(_1); // scope 0 at $DIR/const_goto.rs:+1:17: +1:20 -+ switchInt(move _2) -> [1_isize: bb2, 2_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ switchInt(move _2) -> [1: bb2, 2: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb1: { @@ -29,7 +29,7 @@ - } - - bb3: { -- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- switchInt(move _2) -> [0: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - } - - bb4: { diff --git a/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff b/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff index 623297aeba5..24be8c9b868 100644 --- a/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff +++ b/src/test/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff @@ -10,7 +10,7 @@ StorageLive(_1); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:11: +6:6 StorageLive(_2); // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:15: +2:16 _2 = const A; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:15: +2:16 - switchInt(_2) -> [1_i32: bb2, 2_i32: bb2, 3_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:9: +2:16 + switchInt(_2) -> [1: bb2, 2: bb2, 3: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+2:9: +2:16 } bb1: { @@ -21,11 +21,11 @@ bb2: { _1 = const B; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+3:26: +3:27 - goto -> bb3; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+3:26: +3:27 -+ switchInt(_1) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6 ++ switchInt(_1) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6 } bb3: { -- switchInt(_1) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6 +- switchInt(_1) -> [0: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_const_eval_fail.rs:+1:5: +6:6 - } - - bb4: { diff --git a/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff b/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff index 81c356cb1db..f5457725943 100644 --- a/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff +++ b/src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff @@ -23,10 +23,10 @@ - StorageLive(_5); // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52 - StorageLive(_6); // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 - _6 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 -- switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 +- switchInt(move _6) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 + StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 + _2 = const true; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 -+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 ++ switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:+2:24: +2:28 } bb1: { @@ -41,7 +41,7 @@ - - bb3: { - StorageDead(_6); // scope 0 at $DIR/const_goto_storage.rs:+2:51: +2:52 -- switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52 +- switchInt(move _5) -> [0: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_storage.rs:+2:21: +2:52 - } - - bb4: { @@ -56,7 +56,7 @@ - - bb6: { - StorageDead(_5); // scope 0 at $DIR/const_goto_storage.rs:+2:75: +2:76 -- switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76 +- switchInt(move _4) -> [0: bb8, otherwise: bb7]; // scope 0 at $DIR/const_goto_storage.rs:+2:18: +2:76 - } - - bb7: { @@ -70,7 +70,7 @@ - } - - bb9: { -- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10 +- switchInt(move _3) -> [0: bb11, otherwise: bb10]; // scope 0 at $DIR/const_goto_storage.rs:+2:15: +6:10 - } - - bb10: { diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff index 8b3b9d0a4c1..147670f8a91 100644 --- a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff @@ -9,8 +9,8 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 _1 = const _; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 -- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 -+ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 +- switchInt(move _1) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 ++ switchInt(const false) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21 } bb1: { diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff index 6b29bb59c40..b4dccecc672 100644 --- a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff @@ -21,13 +21,13 @@ ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 discriminant(_3) = 1; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 - _4 = discriminant(_3); // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 -- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 +- switchInt(move _4) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + _4 = const 1_isize; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 -+ switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 ++ switchInt(const 1_isize) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 } bb1: { - switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + switchInt(((_3 as Some).0: bool)) -> [0: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 } bb2: { diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff index 6b29bb59c40..b4dccecc672 100644 --- a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff @@ -21,13 +21,13 @@ ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 discriminant(_3) = 1; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44 - _4 = discriminant(_3); // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 -- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 +- switchInt(move _4) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + _4 = const 1_isize; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 -+ switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 ++ switchInt(const 1_isize) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 } bb1: { - switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 + switchInt(((_3 as Some).0: bool)) -> [0: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31 } bb2: { diff --git a/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff index 9d7c2784d8b..ddc1a4493db 100644 --- a/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff @@ -8,8 +8,8 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 -- switchInt(_1) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 -+ switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 +- switchInt(_1) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 ++ switchInt(const 1_i32) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 } bb1: { diff --git a/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff b/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff index 74f9eafe420..09c47ee6e83 100644 --- a/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff +++ b/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff @@ -8,7 +8,7 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12 -- switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 +- switchInt(const 1_i32) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 + goto -> bb2; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12 } diff --git a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot index fd21b14af25..c4d389b2d76 100644 --- a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot +++ b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot @@ -7,7 +7,7 @@ digraph Cov_0_3 { bcb1__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb1</td></tr><tr><td align="left" balign="left">Expression(bcb0 + bcb3) at 10:5-11:17<br align="left"/> 11:12-11:17: @2.Call: _2 = bar() -> [return: bb3, unwind: bb6]</td></tr><tr><td align="left" balign="left">bb1: FalseUnwind<br align="left"/>bb2: Call</td></tr><tr><td align="left" balign="left">bb3: SwitchInt</td></tr></table>>]; bcb0__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 9:1-9:11<br align="left"/> </td></tr><tr><td align="left" balign="left">bb0: Goto</td></tr></table>>]; bcb3__Cov_0_3 -> bcb1__Cov_0_3 [label=<>]; - bcb1__Cov_0_3 -> bcb3__Cov_0_3 [label=<false>]; + bcb1__Cov_0_3 -> bcb3__Cov_0_3 [label=<0>]; bcb1__Cov_0_3 -> bcb2__Cov_0_3 [label=<otherwise>]; bcb0__Cov_0_3 -> bcb1__Cov_0_3 [label=<>]; } diff --git a/src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff index 2ced794e628..fce18fae436 100644 --- a/src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff +++ b/src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff @@ -28,7 +28,7 @@ discriminant(_1) = 0; // scope 0 at $DIR/enum.rs:+1:13: +1:21 StorageLive(_2); // scope 1 at $DIR/enum.rs:+2:9: +2:10 _3 = discriminant(_1); // scope 1 at $DIR/enum.rs:+2:19: +2:20 - switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/enum.rs:+2:13: +2:20 + switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 1 at $DIR/enum.rs:+2:13: +2:20 } bb1: { diff --git a/src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff index 26808c70fbf..32489b4bd6b 100644 --- a/src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff +++ b/src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff @@ -42,8 +42,8 @@ + _4 = const 1_i32; // scope 1 at $DIR/if.rs:+2:16: +2:17 + _3 = const true; // scope 1 at $DIR/if.rs:+2:16: +2:22 StorageDead(_4); // scope 1 at $DIR/if.rs:+2:21: +2:22 -- switchInt(move _3) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22 -+ switchInt(const true) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22 +- switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22 ++ switchInt(const true) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22 } bb1: { @@ -73,8 +73,8 @@ + _9 = const 1_i32; // scope 3 at $DIR/if.rs:+5:16: +5:17 + _8 = const true; // scope 3 at $DIR/if.rs:+5:16: +5:22 StorageDead(_9); // scope 3 at $DIR/if.rs:+5:21: +5:22 -- switchInt(move _8) -> [false: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22 -+ switchInt(const true) -> [false: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22 +- switchInt(move _8) -> [0: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22 ++ switchInt(const true) -> [0: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22 } bb4: { diff --git a/src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff index 881d80f7c03..5a87884977c 100644 --- a/src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff +++ b/src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff @@ -10,8 +10,8 @@ StorageLive(_1); // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33 StorageLive(_2); // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 _2 = const true; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 -+ switchInt(const true) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 +- switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 ++ switchInt(const true) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 } bb1: { diff --git a/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff index 61d24c3b517..80f8905adc9 100644 --- a/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff +++ b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff @@ -37,8 +37,8 @@ } bb2: { -- switchInt(move _5) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 -+ switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 +- switchInt(move _5) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 ++ switchInt(move _4) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17 } bb3: { diff --git a/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff index fb18089e040..210d3849e18 100644 --- a/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff +++ b/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff @@ -12,7 +12,7 @@ bb0: { StorageLive(_3); // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9 _3 = _1; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9 - switchInt(move _3) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9 + switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/deaggregator_test_enum_2.rs:+1:8: +1:9 } bb1: { diff --git a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff index 995611f0e96..3b1f81175cb 100644 --- a/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff +++ b/src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff @@ -28,44 +28,44 @@ _7 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 _8 = const 4_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 _9 = Ge(move _7, move _8); // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 - switchInt(move _9) -> [false: bb6, otherwise: bb2]; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 + switchInt(move _9) -> [0: bb6, otherwise: bb2]; // scope 0 at $DIR/deduplicate_blocks.rs:+2:9: +2:37 } bb2: { - switchInt((*_2)[0 of 4]) -> [47_u8: bb3, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + switchInt((*_2)[0 of 4]) -> [47: bb3, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 } bb3: { - switchInt((*_2)[1 of 4]) -> [47_u8: bb4, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + switchInt((*_2)[1 of 4]) -> [47: bb4, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 } bb4: { - switchInt((*_2)[2 of 4]) -> [47_u8: bb5, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + switchInt((*_2)[2 of 4]) -> [47: bb5, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 } bb5: { -- switchInt((*_2)[3 of 4]) -> [47_u8: bb11, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 -+ switchInt((*_2)[3 of 4]) -> [47_u8: bb10, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 +- switchInt((*_2)[3 of 4]) -> [47: bb11, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 ++ switchInt((*_2)[3 of 4]) -> [47: bb10, otherwise: bb6]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 } bb6: { _4 = Len((*_2)); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 _5 = const 3_usize; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 _6 = Ge(move _4, move _5); // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 - switchInt(move _6) -> [false: bb10, otherwise: bb7]; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 + switchInt(move _6) -> [0: bb10, otherwise: bb7]; // scope 0 at $DIR/deduplicate_blocks.rs:+3:9: +3:31 } bb7: { - switchInt((*_2)[0 of 3]) -> [47_u8: bb8, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + switchInt((*_2)[0 of 3]) -> [47: bb8, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 } bb8: { - switchInt((*_2)[1 of 3]) -> [47_u8: bb9, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 + switchInt((*_2)[1 of 3]) -> [47: bb9, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 } bb9: { -- switchInt((*_2)[2 of 3]) -> [47_u8: bb12, 33_u8: bb13, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 -+ switchInt((*_2)[2 of 3]) -> [47_u8: bb11, 33_u8: bb11, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 +- switchInt((*_2)[2 of 3]) -> [47: bb12, 33: bb13, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 ++ switchInt((*_2)[2 of 3]) -> [47: bb11, 33: bb11, otherwise: bb10]; // scope 0 at $DIR/deduplicate_blocks.rs:+1:5: +1:23 } bb10: { diff --git a/src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir b/src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir index 5b185082d4d..9597a0c835f 100644 --- a/src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir +++ b/src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir @@ -17,7 +17,7 @@ fn foo(_1: Option<String>) -> i32 { _7 = const false; // scope 0 at $DIR/string.rs:+1:11: +1:12 _7 = const true; // scope 0 at $DIR/string.rs:+1:11: +1:12 _5 = discriminant(_1); // scope 0 at $DIR/string.rs:+1:11: +1:12 - switchInt(move _5) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/string.rs:+1:5: +1:12 + switchInt(move _5) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/string.rs:+1:5: +1:12 } bb1: { @@ -47,7 +47,7 @@ fn foo(_1: Option<String>) -> i32 { } bb4: { - switchInt(move _4) -> [false: bb1, otherwise: bb5]; // scope 0 at $DIR/string.rs:+2:14: +2:17 + switchInt(move _4) -> [0: bb1, otherwise: bb5]; // scope 0 at $DIR/string.rs:+2:14: +2:17 } bb5: { @@ -69,6 +69,6 @@ fn foo(_1: Option<String>) -> i32 { } bb9: { - switchInt(_7) -> [false: bb7, otherwise: bb8]; // scope 0 at $DIR/string.rs:+5:1: +5:2 + switchInt(_7) -> [0: bb7, otherwise: bb8]; // scope 0 at $DIR/string.rs:+5:1: +5:2 } } diff --git a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff index 713d56c3836..fa3eeedc40f 100644 --- a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff +++ b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff @@ -62,7 +62,7 @@ bb3: { StorageDead(_8); // scope 1 at $DIR/derefer_complex_case.rs:+1:25: +1:26 _10 = discriminant(_7); // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 - switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26 } bb4: { diff --git a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff index 60f7b9d5607..ab2388d1323 100644 --- a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff +++ b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff @@ -54,11 +54,11 @@ _6 = &_7; // scope 2 at $DIR/derefer_terminator_test.rs:+3:18: +3:21 _5 = &_6; // scope 2 at $DIR/derefer_terminator_test.rs:+3:17: +3:21 _4 = &_5; // scope 2 at $DIR/derefer_terminator_test.rs:+3:15: +3:22 -- switchInt((*(*(*(*_4))))) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 +- switchInt((*(*(*(*_4))))) -> [0: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 + _10 = deref_copy (*_4); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 + _11 = deref_copy (*_10); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 + _12 = deref_copy (*_11); // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 -+ switchInt((*_12)) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 ++ switchInt((*_12)) -> [0: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:+3:5: +3:22 } bb3: { diff --git a/src/test/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff index 5fa7013d5ca..9c729663265 100644 --- a/src/test/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff +++ b/src/test/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff @@ -37,7 +37,7 @@ } bb2: { - switchInt(move _3) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22 + switchInt(move _3) -> [0: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22 } bb3: { diff --git a/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff index 89d8106ae3c..98a02ee38dd 100644 --- a/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff @@ -31,13 +31,13 @@ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 _7 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 -- switchInt(move _7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- switchInt(move _7) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + _10 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + _11 = Ne(_7, move _10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 -+ switchInt(move _11) -> [false: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(move _11) -> [0: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 } bb1: { @@ -49,7 +49,7 @@ bb2: { - _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 -- switchInt(move _6) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- switchInt(move _6) -> [1: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 - } - - bb3: { @@ -72,7 +72,7 @@ + + bb4: { + StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 -+ switchInt(_7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(_7) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 } } diff --git a/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff index 1a9efa93003..aa75c44b809 100644 --- a/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff @@ -32,18 +32,18 @@ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 _8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 -- switchInt(move _8) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- switchInt(move _8) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + _11 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + _12 = Ne(_8, move _11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 -+ switchInt(move _12) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(move _12) -> [0: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 } bb1: { - _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 -- switchInt(move _6) -> [0_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- switchInt(move _6) -> [0: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 - } - - bb2: { @@ -55,7 +55,7 @@ - bb3: { - _7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 -- switchInt(move _7) -> [1_isize: bb4, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- switchInt(move _7) -> [1: bb4, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 - } - - bb4: { @@ -86,7 +86,7 @@ + + bb5: { + StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 -+ switchInt(_8) -> [0_isize: bb3, 1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(_8) -> [0: bb3, 1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 } } diff --git a/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff index 309a72ae58b..cea6ff7cd05 100644 --- a/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff @@ -31,13 +31,13 @@ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:+1:16: +1:17 _7 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 -- switchInt(move _7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- switchInt(move _7) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + _10 = discriminant((_3.1: std::option::Option<bool>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + _11 = Ne(_7, move _10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 + StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 -+ switchInt(move _11) -> [false: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(move _11) -> [0: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 } bb1: { @@ -49,7 +49,7 @@ bb2: { - _6 = discriminant((_3.1: std::option::Option<bool>)); // scope 0 at $DIR/early_otherwise_branch.rs:+1:11: +1:17 -- switchInt(move _6) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 +- switchInt(move _6) -> [1: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 - } - - bb3: { @@ -72,7 +72,7 @@ + + bb4: { + StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 -+ switchInt(_7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 ++ switchInt(_7) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:+1:5: +1:17 } } diff --git a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff index 9574f32f7f0..b90d70ce43a 100644 --- a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff @@ -42,13 +42,13 @@ StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:19: +1:20 StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:19: +1:20 _10 = discriminant((_4.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 -- switchInt(move _10) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 +- switchInt(move _10) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + StorageLive(_14); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + _14 = discriminant((_4.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + StorageLive(_15); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + _15 = Ne(_10, move _14); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 + StorageDead(_14); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 -+ switchInt(move _15) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ switchInt(move _15) -> [0: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 } bb1: { @@ -61,13 +61,13 @@ bb2: { - _9 = discriminant((_4.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 -- switchInt(move _9) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 +- switchInt(move _9) -> [1: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 - } - - bb3: { _8 = discriminant((_4.2: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:11: +1:20 -- switchInt(move _8) -> [1_isize: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 -+ switchInt(move _8) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 +- switchInt(move _8) -> [1: bb4, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ switchInt(move _8) -> [1: bb3, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 } - bb4: { @@ -94,7 +94,7 @@ + + bb5: { + StorageDead(_15); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 -+ switchInt(_10) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 ++ switchInt(_10) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:+1:5: +1:20 } } diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff index 6bc025bb5b2..9edd1a39f45 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff @@ -80,13 +80,13 @@ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24 _34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 - switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _11) -> [0: bb1, 1: bb3, 2: bb4, 3: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 } bb1: { _35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 - switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _7) -> [0: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 } bb2: { @@ -104,19 +104,19 @@ bb3: { _36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 - switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _8) -> [1: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 } bb4: { _37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 - switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _9) -> [2: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 } bb5: { _38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24 - switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 + switchInt(move _10) -> [3: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24 } bb6: { diff --git a/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff index 321f57951b4..82d8b2fc5a4 100644 --- a/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff @@ -38,12 +38,12 @@ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:16: +1:17 StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:16: +1:17 _8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 - switchInt(move _8) -> [0_isize: bb1, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17 + switchInt(move _8) -> [0: bb1, 1: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17 } bb1: { _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 - switchInt(move _6) -> [0_isize: bb2, 1_isize: bb7, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17 + switchInt(move _6) -> [0: bb2, 1: bb7, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17 } bb2: { @@ -57,7 +57,7 @@ bb4: { _7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:11: +1:17 - switchInt(move _7) -> [0_isize: bb6, 1_isize: bb5, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17 + switchInt(move _7) -> [0: bb6, 1: bb5, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:+1:5: +1:17 } bb5: { diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff index 8b556acb2c4..a3fa2529b18 100644 --- a/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff @@ -14,7 +14,7 @@ bb0: { _3 = discriminant(_1); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:11: +1:12 - switchInt(move _3) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:5: +1:12 + switchInt(move _3) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+1:5: +1:12 } bb1: { @@ -24,7 +24,7 @@ bb2: { _4 = discriminant((*_2)); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+3:26: +3:28 - switchInt(move _4) -> [1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+3:20: +3:28 + switchInt(move _4) -> [1: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:+3:20: +3:28 } bb3: { diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff index 659aed18f04..6d0224b547f 100644 --- a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff @@ -12,13 +12,13 @@ bb0: { _3 = discriminant((*_1)); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 - switchInt(move _3) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + switchInt(move _3) -> [1: bb1, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 } bb1: { _4 = deref_copy (((*_1) as Some).0: &E<'_>); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 _2 = discriminant((*_4)); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 - switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 + switchInt(move _2) -> [1: bb2, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:+1:12: +1:31 } bb2: { diff --git a/src/test/mir-opt/equal_true.opt.InstCombine.diff b/src/test/mir-opt/equal_true.opt.InstCombine.diff index 89982308e71..8b542a7c19d 100644 --- a/src/test/mir-opt/equal_true.opt.InstCombine.diff +++ b/src/test/mir-opt/equal_true.opt.InstCombine.diff @@ -14,7 +14,7 @@ - _2 = Eq(move _3, const true); // scope 0 at $DIR/equal_true.rs:+1:8: +1:17 + _2 = move _3; // scope 0 at $DIR/equal_true.rs:+1:8: +1:17 StorageDead(_3); // scope 0 at $DIR/equal_true.rs:+1:16: +1:17 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/equal_true.rs:+1:8: +1:17 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/equal_true.rs:+1:8: +1:17 } bb1: { diff --git a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir index 08481777ed4..ab955049965 100644 --- a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir @@ -19,7 +19,7 @@ fn match_tuple(_1: (u32, bool, Option<i32>, u32)) -> u32 { bb0: { FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential_or.rs:+1:11: +1:12 - switchInt((_1.0: u32)) -> [1_u32: bb2, 4_u32: bb2, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:15: +2:20 + switchInt((_1.0: u32)) -> [1: bb2, 4: bb2, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:15: +2:20 } bb1: { @@ -29,31 +29,31 @@ fn match_tuple(_1: (u32, bool, Option<i32>, u32)) -> u32 { bb2: { _2 = discriminant((_1.2: std::option::Option<i32>)); // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55 - switchInt(move _2) -> [0_isize: bb4, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55 + switchInt(move _2) -> [0: bb4, 1: bb3, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55 } bb3: { - switchInt((((_1.2: std::option::Option<i32>) as Some).0: i32)) -> [1_i32: bb4, 8_i32: bb4, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55 + switchInt((((_1.2: std::option::Option<i32>) as Some).0: i32)) -> [1: bb4, 8: bb4, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55 } bb4: { _5 = Le(const 6_u32, (_1.3: u32)); // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 - switchInt(move _5) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 + switchInt(move _5) -> [0: bb6, otherwise: bb5]; // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 } bb5: { _6 = Le((_1.3: u32), const 9_u32); // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 - switchInt(move _6) -> [false: bb6, otherwise: bb8]; // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 + switchInt(move _6) -> [0: bb6, otherwise: bb8]; // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67 } bb6: { _3 = Le(const 13_u32, (_1.3: u32)); // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 - switchInt(move _3) -> [false: bb1, otherwise: bb7]; // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 + switchInt(move _3) -> [0: bb1, otherwise: bb7]; // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 } bb7: { _4 = Le((_1.3: u32), const 16_u32); // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 - switchInt(move _4) -> [false: bb1, otherwise: bb8]; // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 + switchInt(move _4) -> [0: bb1, otherwise: bb8]; // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77 } bb8: { diff --git a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff index 6ab63e82e35..c1c2cde71ab 100644 --- a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff +++ b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff @@ -47,7 +47,7 @@ bb1: { StorageDead(_5); // scope 0 at $DIR/funky_arms.rs:+4:36: +4:37 StorageLive(_6); // scope 1 at $DIR/funky_arms.rs:+8:9: +8:13 - switchInt(_4) -> [false: bb3, otherwise: bb2]; // scope 1 at $DIR/funky_arms.rs:+8:16: +8:32 + switchInt(_4) -> [0: bb3, otherwise: bb2]; // scope 1 at $DIR/funky_arms.rs:+8:16: +8:32 } bb2: { @@ -75,7 +75,7 @@ bb5: { StorageDead(_8); // scope 3 at $DIR/funky_arms.rs:+13:44: +13:45 _9 = discriminant(_7); // scope 3 at $DIR/funky_arms.rs:+13:12: +13:27 - switchInt(move _9) -> [1_isize: bb6, otherwise: bb8]; // scope 3 at $DIR/funky_arms.rs:+13:12: +13:27 + switchInt(move _9) -> [1: bb6, otherwise: bb8]; // scope 3 at $DIR/funky_arms.rs:+13:12: +13:27 } bb6: { diff --git a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir index c3b08bf0648..a8e090020c3 100644 --- a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir +++ b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir @@ -29,7 +29,7 @@ fn main::{closure#0}(_1: *mut [generator@$DIR/generator_drop_cleanup.rs:10:15: 1 bb0: { _8 = discriminant((*_1)); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 - switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 + switchInt(move _8) -> [0: bb7, 3: bb10, otherwise: bb11]; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6 } bb1: { diff --git a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir index fee6da2c635..b3d3c768a5d 100644 --- a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir +++ b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir @@ -32,7 +32,7 @@ fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator_tiny.rs:19:16: 19:24 bb0: { _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 - switchInt(move _11) -> [0_u32: bb1, 3_u32: bb5, otherwise: bb6]; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 + switchInt(move _11) -> [0: bb1, 3: bb5, otherwise: bb6]; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6 } bb1: { diff --git a/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff index 94180d20343..de4235c9e9e 100644 --- a/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 _2 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 } bb1: { diff --git a/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff index b22c7eac622..754c6579af0 100644 --- a/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff @@ -13,7 +13,7 @@ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 _2 = Eq(move _3, const -42f32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18 StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:17: +1:18 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18 } bb1: { diff --git a/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff index cc0995f99cf..ff23839e291 100644 --- a/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff @@ -20,10 +20,10 @@ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:14 - _2 = Eq(move _3, const 17_i8); // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:20 - StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20 -- switchInt(_2) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12 +- switchInt(_2) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12 + _2 = Eq(_3, const 17_i8); // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:20 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20 -+ switchInt(move _3) -> [17_i8: bb1, otherwise: bb2]; // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12 ++ switchInt(move _3) -> [17: bb1, otherwise: bb2]; // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12 } bb1: { diff --git a/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff index 801ea040203..5964d76a4b9 100644 --- a/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff @@ -13,10 +13,10 @@ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 - _2 = Eq(move _3, const 'x'); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 - StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 +- switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16 -+ switchInt(move _3) -> ['x': bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 ++ switchInt(move _3) -> [120: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 } bb1: { diff --git a/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff index 4297f4d6466..98918cc743c 100644 --- a/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff @@ -13,10 +13,10 @@ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 - _2 = Eq(move _3, const 42_i8); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 - StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 +- switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 -+ switchInt(move _3) -> [42_i8: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 ++ switchInt(move _3) -> [42: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 } bb1: { diff --git a/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff index 8fb794abbd4..db38140b8d0 100644 --- a/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff @@ -15,10 +15,10 @@ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 - _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 - StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 +- switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 -+ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 ++ switchInt(move _3) -> [42: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 } bb1: { @@ -34,10 +34,10 @@ _5 = _1; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:16 - _4 = Ne(move _5, const 21_u32); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 - StorageDead(_5); // scope 0 at $DIR/if_condition_int.rs:+3:21: +3:22 -- switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 +- switchInt(move _4) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 + nop; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 + nop; // scope 0 at $DIR/if_condition_int.rs:+3:21: +3:22 -+ switchInt(move _5) -> [21_u32: bb4, otherwise: bb3]; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 ++ switchInt(move _5) -> [21: bb4, otherwise: bb3]; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22 } bb3: { diff --git a/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff index 992253ea780..1a1ac4caafa 100644 --- a/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff @@ -13,10 +13,10 @@ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 - _2 = Eq(move _3, const -42_i32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 - StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 +- switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16 -+ switchInt(move _3) -> [-42_i32: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 ++ switchInt(move _3) -> [4294967254: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16 } bb1: { diff --git a/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff index 7cea9472d3a..fc3f50227dc 100644 --- a/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff @@ -13,10 +13,10 @@ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9 - _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 - StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 -- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 +- switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 + nop; // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15 -+ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 ++ switchInt(move _3) -> [42: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15 } bb1: { diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff index 1e703a8fd2b..b787a19f4b2 100644 --- a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff @@ -19,7 +19,7 @@ _3 = _1; // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9 _2 = Gt(move _3, const 0_i32); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 StorageDead(_3); // scope 0 at $DIR/inline_diverging.rs:+1:12: +1:13 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13 } bb1: { diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff index 91bff3d3234..bd21405f14b 100644 --- a/src/test/mir-opt/inline/inline_generator.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff @@ -72,7 +72,7 @@ + _7 = const false; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 + _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 + _9 = discriminant((*_10)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 -+ switchInt(move _9) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ switchInt(move _9) -> [0: bb3, 1: bb8, 3: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 } - bb3: { @@ -92,7 +92,7 @@ + + bb3: { + StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 -+ switchInt(move _7) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21 ++ switchInt(move _7) -> [0: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21 + } + + bb4: { diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir index 75af20d482d..60149ff3606 100644 --- a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir @@ -38,9 +38,7 @@ fn bar() -> bool { // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) } Retag(_10); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 _4 = &(*_10); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 - Retag(_4); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 _3 = &(*_4); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 - Retag(_3); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9 StorageLive(_6); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 StorageLive(_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 _9 = const _; // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 @@ -49,9 +47,7 @@ fn bar() -> bool { // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) } Retag(_9); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 _7 = &(*_9); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 - Retag(_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 _6 = &(*_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 - Retag(_6); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14 Retag(_3); // scope 2 at $DIR/inline_retag.rs:16:8: 16:9 Retag(_6); // scope 2 at $DIR/inline_retag.rs:16:17: 16:18 StorageLive(_11); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7 diff --git a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff index 7a54beca233..36ddb189e0d 100644 --- a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff +++ b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff @@ -39,7 +39,7 @@ + StorageLive(_6); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 + StorageLive(_7); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40 + _6 = discriminant((*_5)); // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL -+ switchInt(move _6) -> [0_isize: bb2, otherwise: bb3]; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ switchInt(move _6) -> [0: bb2, otherwise: bb3]; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL } bb2: { diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff index 81d5528231d..2f6f5f87efc 100644 --- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -26,7 +26,7 @@ } bb3: { - switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17 + switchInt(move _2) -> [0: bb5, otherwise: bb4]; // scope 0 at /the/src/instrument_coverage.rs:+2:12: +2:17 } bb4: { diff --git a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir index 82210081832..b0d5b291b6c 100644 --- a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir @@ -26,7 +26,7 @@ fn main() -> () { StorageLive(_3); // scope 1 at $DIR/issue_38669.rs:+3:9: +5:10 StorageLive(_4); // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24 _4 = _1; // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24 - switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24 + switchInt(move _4) -> [0: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24 } bb3: { diff --git a/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir index c573ad5a8e4..c2ea3ac502f 100644 --- a/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir @@ -65,6 +65,6 @@ fn main() -> () { } bb8 (cleanup): { - switchInt(_5) -> [false: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + switchInt(_5) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 } } diff --git a/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir index 470b0323281..82989c3f071 100644 --- a/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir @@ -96,6 +96,6 @@ fn test() -> () { } bb14 (cleanup): { - switchInt(_6) -> [false: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + switchInt(_6) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 } } diff --git a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir index 73372c97bea..00504273245 100644 --- a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir @@ -33,7 +33,7 @@ fn main() -> () { } bb1: { - switchInt(move _2) -> [false: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 + switchInt(move _2) -> [0: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 } bb2: { @@ -52,7 +52,7 @@ fn main() -> () { bb4: { StorageDead(_3); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 _5 = discriminant(_1); // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 - switchInt(move _5) -> [0_isize: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 + switchInt(move _5) -> [0: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 } bb5: { @@ -134,19 +134,19 @@ fn main() -> () { bb19: { _10 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - switchInt(move _10) -> [0_isize: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + switchInt(move _10) -> [0: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb20: { - switchInt(_7) -> [false: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + switchInt(_7) -> [0: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb21 (cleanup): { _11 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - switchInt(move _11) -> [0_isize: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + switchInt(move _11) -> [0: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } bb22 (cleanup): { - switchInt(_7) -> [false: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } } diff --git a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir index 6969a66ac19..adfa3a7733b 100644 --- a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir +++ b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir @@ -52,7 +52,7 @@ fn test() -> Option<Box<u32>> { bb2: { StorageDead(_7); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20 _8 = discriminant(_6); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 - switchInt(move _8) -> [0_isize: bb3, 1_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 + switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb4]; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20 } bb3: { diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff index b88cdfcbc96..17b81633991 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff @@ -116,7 +116,7 @@ StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(move _15) -> [false: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _15) -> [0: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb4: { diff --git a/src/test/mir-opt/issue_99325.main.built.after.mir b/src/test/mir-opt/issue_99325.main.built.after.mir index 3db40412b2e..3e035c18db8 100644 --- a/src/test/mir-opt/issue_99325.main.built.after.mir +++ b/src/test/mir-opt/issue_99325.main.built.after.mir @@ -109,7 +109,7 @@ fn main() -> () { StorageDead(_12); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _10 = Not(move _11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(move _10) -> [false: bb4, otherwise: bb3]; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _10) -> [0: bb4, otherwise: bb3]; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb3: { @@ -218,7 +218,7 @@ fn main() -> () { StorageDead(_33); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _31 = Not(move _32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(move _31) -> [false: bb13, otherwise: bb12]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _31) -> [0: bb13, otherwise: bb12]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb12: { diff --git a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir index 5a2f4feff35..e0d6b58f229 100644 --- a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir +++ b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -47,7 +47,7 @@ fn num_to_digit(_1: char) -> u32 { bb2: { _7 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _7) -> [0_isize: bb6, 1_isize: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _7) -> [0: bb6, 1: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL } bb3: { @@ -66,7 +66,7 @@ fn num_to_digit(_1: char) -> u32 { StorageDead(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageDead(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageDead(_3); // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 - switchInt(move _9) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + switchInt(move _9) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 } bb6: { diff --git a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff index 87066cc62c0..1c69a6232d6 100644 --- a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff +++ b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff @@ -32,15 +32,15 @@ bb1: { StorageDead(_3); // scope 2 at $DIR/issue_75439.rs:+2:52: +2:53 - switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 + switchInt(_2[0 of 4]) -> [0: bb2, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 } bb2: { - switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 + switchInt(_2[1 of 4]) -> [0: bb3, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 } bb3: { - switchInt(_2[2 of 4]) -> [0_u32: bb5, 4294901760_u32: bb6, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 + switchInt(_2[2 of 4]) -> [0: bb5, 4294901760: bb6, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30 } bb4: { diff --git a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir index 5981ab885f9..4ee2dae49b3 100644 --- a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir +++ b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir @@ -16,7 +16,7 @@ fn main() -> () { StorageLive(_1); // scope 0 at $DIR/loop_test.rs:+4:5: +6:6 StorageLive(_2); // scope 0 at $DIR/loop_test.rs:+4:8: +4:12 _2 = const true; // scope 0 at $DIR/loop_test.rs:+4:8: +4:12 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/loop_test.rs:+4:8: +4:12 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/loop_test.rs:+4:8: +4:12 } bb1: { diff --git a/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff index 049bbeac867..9bc7060e958 100644 --- a/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff +++ b/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff @@ -38,7 +38,7 @@ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 - switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + switchInt(move _3) -> [0: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 } bb2: { diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff index 40ec01eeb41..cf427cfd1e6 100644 --- a/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff +++ b/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff @@ -41,7 +41,7 @@ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27 - switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 + switchInt(move _3) -> [0: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27 } bb2: { diff --git a/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir b/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir index 9b1b07f38fc..701c2ad705a 100644 --- a/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir +++ b/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir @@ -19,7 +19,7 @@ fn array_bound(_1: usize, _2: &[u8; N]) -> u8 { _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27 StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27 - switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + switchInt(move _3) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 } bb1: { diff --git a/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir b/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir index 29e379777b0..0440cfce289 100644 --- a/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir +++ b/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir @@ -22,7 +22,7 @@ fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 { _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27 StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27 - switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 + switchInt(move _3) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27 } bb1: { diff --git a/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff b/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff index 5f5d6e68fdc..2b0370cf358 100644 --- a/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff +++ b/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff @@ -33,7 +33,7 @@ _3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 StorageDead(_5); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27 StorageDead(_4); // scope 0 at $DIR/lower_slice_len.rs:+1:26: +1:27 - switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 + switchInt(move _3) -> [0: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_slice_len.rs:+1:8: +1:27 } bb2: { diff --git a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff index d3db3b18271..84e4d35f908 100644 --- a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff +++ b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -32,18 +32,18 @@ bb0: { - FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16 -- switchInt((_2.0: bool)) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 -+ switchInt((_2.0: bool)) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 +- switchInt((_2.0: bool)) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [0: bb5, otherwise: bb1]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 } bb1: { - falseEdge -> [real: bb8, imaginary: bb3]; // scope 0 at $DIR/match_arm_scopes.rs:+2:9: +2:22 -+ switchInt((_2.1: bool)) -> [false: bb10, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 ++ switchInt((_2.1: bool)) -> [0: bb10, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 } bb2: { -- switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 -+ switchInt((_2.0: bool)) -> [false: bb3, otherwise: bb17]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 +- switchInt((_2.1: bool)) -> [0: bb3, otherwise: bb4]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 ++ switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 } bb3: { @@ -51,7 +51,7 @@ - } - - bb4: { -- switchInt((_2.0: bool)) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 +- switchInt((_2.0: bool)) -> [0: bb6, otherwise: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16 - } - - bb5: { @@ -85,8 +85,8 @@ StorageLive(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 StorageLive(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 _10 = _1; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 -- switchInt(move _10) -> [false: bb10, otherwise: bb9]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 -+ switchInt(move _10) -> [false: bb7, otherwise: bb6]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 +- switchInt(move _10) -> [0: bb10, otherwise: bb9]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 ++ switchInt(move _10) -> [0: bb7, otherwise: bb6]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 } - bb9: { @@ -101,8 +101,8 @@ - bb10: { + bb7: { _9 = (*_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:70: +2:71 -- switchInt(move _9) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 -+ switchInt(move _9) -> [false: bb9, otherwise: bb8]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 +- switchInt(move _9) -> [0: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ switchInt(move _9) -> [0: bb9, otherwise: bb8]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 } - bb11: { @@ -142,8 +142,8 @@ StorageLive(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 StorageLive(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 _13 = _1; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 -- switchInt(move _13) -> [false: bb15, otherwise: bb14]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 -+ switchInt(move _13) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 +- switchInt(move _13) -> [0: bb15, otherwise: bb14]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 ++ switchInt(move _13) -> [0: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49 } - bb14: { @@ -158,8 +158,8 @@ - bb15: { + bb12: { _12 = (*_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:70: +2:71 -- switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 -+ switchInt(move _12) -> [false: bb14, otherwise: bb13]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 +- switchInt(move _12) -> [0: bb17, otherwise: bb16]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 ++ switchInt(move _12) -> [0: bb14, otherwise: bb13]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73 } - bb16: { diff --git a/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir index b184ffc404e..d51dbf4258c 100644 --- a/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir @@ -28,12 +28,12 @@ fn main() -> () { StorageLive(_3); // scope 2 at $DIR/match_test.rs:+6:5: +11:6 FakeRead(ForMatchedPlace(None), _1); // scope 2 at $DIR/match_test.rs:+6:11: +6:12 _6 = Le(const 0_i32, _1); // scope 2 at $DIR/match_test.rs:+7:9: +7:14 - switchInt(move _6) -> [false: bb4, otherwise: bb1]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14 + switchInt(move _6) -> [0: bb4, otherwise: bb1]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14 } bb1: { _7 = Lt(_1, const 10_i32); // scope 2 at $DIR/match_test.rs:+7:9: +7:14 - switchInt(move _7) -> [false: bb4, otherwise: bb2]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14 + switchInt(move _7) -> [0: bb4, otherwise: bb2]; // scope 2 at $DIR/match_test.rs:+7:9: +7:14 } bb2: { @@ -47,12 +47,12 @@ fn main() -> () { bb4: { _4 = Le(const 10_i32, _1); // scope 2 at $DIR/match_test.rs:+8:9: +8:16 - switchInt(move _4) -> [false: bb7, otherwise: bb5]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16 + switchInt(move _4) -> [0: bb7, otherwise: bb5]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16 } bb5: { _5 = Le(_1, const 20_i32); // scope 2 at $DIR/match_test.rs:+8:9: +8:16 - switchInt(move _5) -> [false: bb7, otherwise: bb6]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16 + switchInt(move _5) -> [0: bb7, otherwise: bb6]; // scope 2 at $DIR/match_test.rs:+8:9: +8:16 } bb6: { @@ -60,7 +60,7 @@ fn main() -> () { } bb7: { - switchInt(_1) -> [-1_i32: bb8, otherwise: bb3]; // scope 2 at $DIR/match_test.rs:+6:5: +6:12 + switchInt(_1) -> [4294967295: bb8, otherwise: bb3]; // scope 2 at $DIR/match_test.rs:+6:5: +6:12 } bb8: { @@ -71,7 +71,7 @@ fn main() -> () { _8 = &shallow _1; // scope 2 at $DIR/match_test.rs:+6:11: +6:12 StorageLive(_9); // scope 2 at $DIR/match_test.rs:+7:18: +7:19 _9 = _2; // scope 2 at $DIR/match_test.rs:+7:18: +7:19 - switchInt(move _9) -> [false: bb11, otherwise: bb10]; // scope 2 at $DIR/match_test.rs:+7:18: +7:19 + switchInt(move _9) -> [0: bb11, otherwise: bb10]; // scope 2 at $DIR/match_test.rs:+7:18: +7:19 } bb10: { diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff index f9eeb1ea5b9..be91b0bfe68 100644 --- a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff +++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.diff @@ -33,7 +33,7 @@ StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:+3:9: +3:10 StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:+4:9: +4:10 StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +21:6 -- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 +- switchInt(_1) -> [7: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:+6:5: +6:12 - } - - bb1: { diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff index 0b40b3be8bd..aa8092ece66 100644 --- a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff +++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.diff @@ -11,12 +11,12 @@ bb0: { StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20 -- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _4 = move _3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _2 = Eq(_4, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL -+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb1: { @@ -30,7 +30,7 @@ - } - - bb3: { -- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL +- switchInt(move _2) -> [0: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - } - - bb4: { diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff index b8c7722cd37..193104dd30e 100644 --- a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff +++ b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff @@ -26,7 +26,7 @@ StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 _6 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 -- switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 +- switchInt(move _6) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 - } - - bb1: { @@ -45,7 +45,7 @@ + _5 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50 + StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28 StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52 -- switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 +- switchInt(move _5) -> [0: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 - } - - bb4: { @@ -64,7 +64,7 @@ + _4 = Ne(_8, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74 + StorageDead(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52 StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:75: +2:76 -- switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 +- switchInt(move _4) -> [0: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76 - } - - bb7: { @@ -78,7 +78,7 @@ - } - - bb9: { -- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 +- switchInt(move _3) -> [0: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10 - } - - bb10: { diff --git a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff index 1b4dddc1d43..3766d99a43b 100644 --- a/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff +++ b/src/test/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff @@ -8,7 +8,7 @@ bb0: { _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12 - switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12 + switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12 } bb1: { diff --git a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff index 6e734852e1a..b5146cd539f 100644 --- a/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff +++ b/src/test/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff @@ -8,7 +8,7 @@ bb0: { _2 = discriminant(_1); // scope 0 at $DIR/matches_u8.rs:+1:11: +1:12 - switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12 + switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/matches_u8.rs:+1:5: +1:12 } bb1: { diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 3e3fda6141a..8e6564a38b0 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -62,7 +62,7 @@ fn main() -> () { FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 StorageLive(_7); // bb1[5]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 - switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 + switchInt(move _7) -> [0: bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 } bb2: { diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 39a53702a4c..74d44c6741a 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -62,7 +62,7 @@ fn main() -> () { FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 StorageLive(_7); // bb1[5]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 - switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 + switchInt(move _7) -> [0: bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12 } bb2: { diff --git a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir index e708255cea4..69327b7afac 100644 --- a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir @@ -15,7 +15,7 @@ fn unwrap(_1: Option<T>) -> T { bb0: { _2 = discriminant(_1); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:11: +1:14 - switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:5: +1:14 + switchInt(move _2) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:5: +1:14 } bb1: { diff --git a/src/test/mir-opt/not_equal_false.opt.InstCombine.diff b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff index 5009d090668..b558c35ac1e 100644 --- a/src/test/mir-opt/not_equal_false.opt.InstCombine.diff +++ b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff @@ -14,7 +14,7 @@ - _2 = Ne(move _3, const false); // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18 + _2 = move _3; // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18 StorageDead(_3); // scope 0 at $DIR/not_equal_false.rs:+1:17: +1:18 - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:+1:8: +1:18 } bb1: { diff --git a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff index 243a54b6a84..bb5920b28ca 100644 --- a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff +++ b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff @@ -16,7 +16,7 @@ - FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 + nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 _3 = discriminant(_1); // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 - switchInt(move _3) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12 + switchInt(move _3) -> [1: bb2, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12 } bb1: { @@ -25,7 +25,7 @@ } bb2: { - switchInt((*(*((_1 as Some).0: &&i32)))) -> [0_i32: bb3, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12 + switchInt((*(*((_1 as Some).0: &&i32)))) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+1:5: +1:12 } bb3: { @@ -43,7 +43,7 @@ + nop; // scope 0 at $DIR/remove_fake_borrows.rs:+1:11: +1:12 StorageLive(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 _8 = _2; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 - switchInt(move _8) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 + switchInt(move _8) -> [0: bb6, otherwise: bb5]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 } bb5: { diff --git a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff index 188aa556490..ed1d0b87f60 100644 --- a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff +++ b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff @@ -63,7 +63,7 @@ bb3: { - StorageDead(_8); // scope 2 at $DIR/remove_storage_markers.rs:+2:18: +2:19 _10 = discriminant(_7); // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 - switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 + switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 2 at $DIR/remove_storage_markers.rs:+2:14: +2:19 } bb4: { diff --git a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir index fe57e32a7ac..19b726e7484 100644 --- a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir @@ -68,9 +68,7 @@ fn array_casts() -> () { StorageLive(_3); // scope 1 at $DIR/retag.rs:+2:13: +2:19 StorageLive(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19 _4 = &mut _1; // scope 1 at $DIR/retag.rs:+2:13: +2:19 - Retag(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19 _3 = &raw mut (*_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19 - Retag([raw] _3); // scope 1 at $DIR/retag.rs:+2:13: +2:19 _2 = move _3 as *mut usize (Pointer(ArrayToPointer)); // scope 1 at $DIR/retag.rs:+2:13: +2:33 StorageDead(_3); // scope 1 at $DIR/retag.rs:+2:32: +2:33 StorageDead(_4); // scope 1 at $DIR/retag.rs:+2:33: +2:34 @@ -96,9 +94,7 @@ fn array_casts() -> () { StorageLive(_10); // scope 4 at $DIR/retag.rs:+6:13: +6:15 StorageLive(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15 _11 = &_8; // scope 4 at $DIR/retag.rs:+6:13: +6:15 - Retag(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15 _10 = &raw const (*_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15 - Retag([raw] _10); // scope 4 at $DIR/retag.rs:+6:13: +6:15 _9 = move _10 as *const usize (Pointer(ArrayToPointer)); // scope 4 at $DIR/retag.rs:+6:13: +6:31 StorageDead(_10); // scope 4 at $DIR/retag.rs:+6:30: +6:31 StorageDead(_11); // scope 4 at $DIR/retag.rs:+6:31: +6:32 @@ -119,7 +115,6 @@ fn array_casts() -> () { StorageDead(_17); // scope 6 at $DIR/retag.rs:+7:33: +7:34 _15 = (*_16); // scope 6 at $DIR/retag.rs:+7:25: +7:34 _14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _35 = const _; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant @@ -127,7 +122,6 @@ fn array_casts() -> () { // + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) } Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL Deinit(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_13.0: &usize) = move _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_13.1: &usize) = move _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -151,7 +145,7 @@ fn array_casts() -> () { StorageDead(_24); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _22 = Not(move _23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(move _22) -> [false: bb4, otherwise: bb3]; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _22) -> [0: bb4, otherwise: bb3]; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb3: { @@ -164,15 +158,11 @@ fn array_casts() -> () { StorageLive(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _31 = &(*_20); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Retag(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _30 = &(*_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Retag(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _33 = &(*_21); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Retag(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _32 = &(*_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL Deinit(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL discriminant(_34) = 0; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL diff --git a/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir index cdc413c568f..14f297e948b 100644 --- a/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir +++ b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir @@ -6,7 +6,6 @@ fn std::ptr::drop_in_place(_1: *mut Test) -> () { let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 bb0: { - Retag([raw] _1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 _3 = <Test as Drop>::drop(move _2) -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 // mir::Constant diff --git a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir index 96fc7e6493a..9e5c119a2b2 100644 --- a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir @@ -15,7 +15,6 @@ fn main::{closure#0}(_1: &[closure@main::{closure#0}], _2: &i32) -> &i32 { _3 = _2; // scope 0 at $DIR/retag.rs:+1:18: +1:19 Retag(_3); // scope 0 at $DIR/retag.rs:+1:18: +1:19 _0 = &(*_2); // scope 1 at $DIR/retag.rs:+2:9: +2:10 - Retag(_0); // scope 1 at $DIR/retag.rs:+2:9: +2:10 StorageDead(_3); // scope 0 at $DIR/retag.rs:+3:5: +3:6 return; // scope 0 at $DIR/retag.rs:+3:6: +3:6 } diff --git a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir index 81225b44ebf..b853e450541 100644 --- a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir @@ -65,13 +65,10 @@ fn main() -> () { Deinit(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24 (_5.0: i32) = const 0_i32; // scope 1 at $DIR/retag.rs:+3:17: +3:24 _4 = &_5; // scope 1 at $DIR/retag.rs:+3:17: +3:36 - Retag(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36 StorageLive(_6); // scope 1 at $DIR/retag.rs:+3:29: +3:35 StorageLive(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35 _7 = &mut _1; // scope 1 at $DIR/retag.rs:+3:29: +3:35 - Retag(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35 _6 = &mut (*_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35 - Retag([2phase] _6); // scope 1 at $DIR/retag.rs:+3:29: +3:35 _3 = Test::foo(move _4, move _6) -> [return: bb1, unwind: bb8]; // scope 1 at $DIR/retag.rs:+3:17: +3:36 // mir::Constant // + span: $DIR/retag.rs:33:25: 33:28 @@ -93,7 +90,6 @@ fn main() -> () { _9 = move _3; // scope 2 at $DIR/retag.rs:+4:19: +4:20 Retag(_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20 _8 = &mut (*_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20 - Retag(_8); // scope 2 at $DIR/retag.rs:+4:19: +4:20 StorageDead(_9); // scope 2 at $DIR/retag.rs:+4:22: +4:23 StorageLive(_10); // scope 3 at $DIR/retag.rs:+5:13: +5:14 _10 = move _8; // scope 3 at $DIR/retag.rs:+5:17: +5:18 @@ -101,7 +97,6 @@ fn main() -> () { StorageLive(_11); // scope 4 at $DIR/retag.rs:+7:13: +7:15 StorageLive(_12); // scope 4 at $DIR/retag.rs:+7:18: +7:29 _12 = &raw mut (*_10); // scope 4 at $DIR/retag.rs:+7:18: +7:19 - Retag([raw] _12); // scope 4 at $DIR/retag.rs:+7:18: +7:19 _11 = _12; // scope 4 at $DIR/retag.rs:+7:18: +7:29 StorageDead(_12); // scope 4 at $DIR/retag.rs:+7:29: +7:30 _2 = const (); // scope 1 at $DIR/retag.rs:+2:5: +8:6 @@ -122,9 +117,7 @@ fn main() -> () { StorageLive(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18 StorageLive(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18 _18 = &_1; // scope 6 at $DIR/retag.rs:+15:16: +15:18 - Retag(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18 _17 = &(*_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18 - Retag(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18 _15 = move _16(move _17) -> bb3; // scope 6 at $DIR/retag.rs:+15:14: +15:19 } @@ -139,7 +132,6 @@ fn main() -> () { Deinit(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12 (_21.0: i32) = const 0_i32; // scope 7 at $DIR/retag.rs:+18:5: +18:12 _20 = &_21; // scope 7 at $DIR/retag.rs:+18:5: +18:24 - Retag(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24 StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23 StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23 _28 = const _; // scope 7 at $DIR/retag.rs:+18:21: +18:23 @@ -148,9 +140,7 @@ fn main() -> () { // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } Retag(_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23 _23 = &(*_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23 - Retag(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23 _22 = &(*_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23 - Retag(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23 _19 = Test::foo_shr(move _20, move _22) -> [return: bb4, unwind: bb7]; // scope 7 at $DIR/retag.rs:+18:5: +18:24 // mir::Constant // + span: $DIR/retag.rs:48:13: 48:20 @@ -171,7 +161,6 @@ fn main() -> () { StorageLive(_25); // scope 7 at $DIR/retag.rs:+21:9: +21:11 StorageLive(_26); // scope 7 at $DIR/retag.rs:+21:14: +21:28 _26 = &raw const (*_15); // scope 7 at $DIR/retag.rs:+21:14: +21:16 - Retag([raw] _26); // scope 7 at $DIR/retag.rs:+21:14: +21:16 _25 = _26; // scope 7 at $DIR/retag.rs:+21:14: +21:28 StorageDead(_26); // scope 7 at $DIR/retag.rs:+21:28: +21:29 StorageLive(_27); // scope 8 at $DIR/retag.rs:+23:5: +23:18 diff --git a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir index 08fd655ae29..4b50205fa80 100644 --- a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir @@ -11,9 +11,7 @@ fn <impl at $DIR/retag.rs:12:1: 12:10>::foo(_1: &Test, _2: &mut i32) -> &mut i32 Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:23: +0:24 StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 _3 = &mut (*_2); // scope 0 at $DIR/retag.rs:+1:9: +1:10 - Retag(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 _0 = &mut (*_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10 - Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10 StorageDead(_3); // scope 0 at $DIR/retag.rs:+2:5: +2:6 return; // scope 0 at $DIR/retag.rs:+2:6: +2:6 } diff --git a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff index b28c6f687f7..6ae16bdb5b8 100644 --- a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff +++ b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -53,14 +53,14 @@ StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -- switchInt(move _10) -> [0_isize: bb7, 1_isize: bb5, otherwise: bb6]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL +- switchInt(move _10) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL } bb1: { - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -- switchInt(move _5) -> [0_isize: bb2, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 +- switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - } - - bb2: { @@ -118,7 +118,7 @@ - goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 } - bb6: { @@ -140,7 +140,7 @@ - goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 + _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 ++ switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 } - bb8: { diff --git a/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff index 43797908136..8cc0c6a1835 100644 --- a/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff +++ b/src/test/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff @@ -30,7 +30,7 @@ bb0: { StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 - switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16 + switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16 } bb1: { @@ -45,7 +45,7 @@ StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 - goto -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 + _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -+ switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 ++ switchInt(move _8) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 } bb2: { @@ -67,8 +67,8 @@ - - bb4: { _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -- switchInt(move _8) -> [0_isize: bb7, 1_isize: bb5, otherwise: bb6]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 -+ switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 +- switchInt(move _8) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 ++ switchInt(move _8) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 } - bb5: { diff --git a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff index e068b81bc3b..8eb1aa1f3b3 100644 --- a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff +++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff @@ -25,9 +25,9 @@ } - bb3: { -- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 +- switchInt(move _2) -> [0: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 + bb2: { -+ switchInt(move _2) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 ++ switchInt(move _2) -> [0: bb4, otherwise: bb3]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 } - bb4: { diff --git a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff index f693798eb94..1e66b1f703e 100644 --- a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff +++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff @@ -26,7 +26,7 @@ } bb3: { - switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 + switchInt(move _2) -> [0: bb5, otherwise: bb4]; // scope 0 at $DIR/simplify_cfg.rs:+2:12: +2:17 } bb4: { diff --git a/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff b/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff index 9b1bea2704b..aea01147443 100644 --- a/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff +++ b/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 _1 = const false; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 -- switchInt(const false) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 +- switchInt(const false) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 + goto -> bb3; // scope 0 at $DIR/simplify_if.rs:+1:8: +1:13 } diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff index 8feddcef2ce..a2b55229303 100644 --- a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff @@ -29,12 +29,12 @@ StorageDead(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 StorageDead(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 _5 = discriminant((_1.0: std::option::Option<u8>)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 - switchInt(move _5) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + switchInt(move _5) -> [1: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 } bb1: { _4 = discriminant((_1.1: std::option::Option<T>)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 - switchInt(move _4) -> [0_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + switchInt(move _4) -> [0: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 } bb2: { diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff index 6e7294003af..9ec138dd82f 100644 --- a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff @@ -18,7 +18,7 @@ - _5 = const false; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 - _5 = const true; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 _2 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 - switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:5: +1:12 + switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:5: +1:12 } bb1: { diff --git a/src/test/mir-opt/simplify_match.main.ConstProp.diff b/src/test/mir-opt/simplify_match.main.ConstProp.diff index e4f9a4c12d9..f00ac5716a7 100644 --- a/src/test/mir-opt/simplify_match.main.ConstProp.diff +++ b/src/test/mir-opt/simplify_match.main.ConstProp.diff @@ -16,8 +16,8 @@ - _1 = _2; // scope 1 at $DIR/simplify_match.rs:+1:28: +1:29 + _1 = const false; // scope 1 at $DIR/simplify_match.rs:+1:28: +1:29 StorageDead(_2); // scope 0 at $DIR/simplify_match.rs:+1:30: +1:31 -- switchInt(_1) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 -+ switchInt(const false) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 +- switchInt(_1) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 ++ switchInt(const false) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31 } bb1: { diff --git a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir index 31ccf14549c..391b00effac 100644 --- a/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir +++ b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir @@ -37,7 +37,7 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () { bb4 (cleanup): { _6 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - switchInt(move _6) -> [false: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _6) -> [0: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 } bb5: { @@ -48,7 +48,7 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () { bb6: { _8 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - switchInt(move _8) -> [false: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _8) -> [0: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 } bb7: { @@ -68,7 +68,7 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () { bb10 (cleanup): { _12 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - switchInt(move _12) -> [false: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _12) -> [0: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 } bb11: { @@ -79,7 +79,7 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () { bb12: { _14 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - switchInt(move _14) -> [false: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _14) -> [0: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 } bb13: { @@ -96,6 +96,6 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () { bb15: { _2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 _3 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - switchInt(move _2) -> [0_usize: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + switchInt(move _2) -> [0: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 } } diff --git a/src/test/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff b/src/test/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff index 7c7e87c32a2..a5488c1ec7b 100644 --- a/src/test/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff +++ b/src/test/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff @@ -21,7 +21,7 @@ discriminant(_2) = 1; // scope 1 at $DIR/sroa.rs:+1:22: +1:29 StorageDead(_3); // scope 1 at $DIR/sroa.rs:+1:28: +1:29 _4 = discriminant(_2); // scope 1 at $DIR/sroa.rs:+1:12: +1:19 - switchInt(move _4) -> [1_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/sroa.rs:+1:12: +1:19 + switchInt(move _4) -> [1: bb1, otherwise: bb2]; // scope 1 at $DIR/sroa.rs:+1:12: +1:19 } bb1: { diff --git a/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir b/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir index 30185f3ffab..b254bfeb7c9 100644 --- a/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir +++ b/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir @@ -26,7 +26,7 @@ fn new(_1: Result<T, E>) -> Result<T, E> { bb0: { StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 _3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20 - switchInt(move _3) -> [0_isize: bb2, 1_isize: bb1, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20 + switchInt(move _3) -> [0: bb2, 1: bb1, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20 } bb1: { @@ -35,7 +35,7 @@ fn new(_1: Result<T, E>) -> Result<T, E> { ((_2 as Break).0: E) = move _5; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48 discriminant(_2) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48 _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 - switchInt(move _6) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10 + switchInt(move _6) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10 } bb2: { @@ -44,7 +44,7 @@ fn new(_1: Result<T, E>) -> Result<T, E> { ((_2 as Continue).0: T) = move _4; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50 discriminant(_2) = 0; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50 _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 - switchInt(move _6) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10 + switchInt(move _6) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10 } bb3: { diff --git a/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir b/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir index 2a9c7408c66..cdbc0681cb8 100644 --- a/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir +++ b/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir @@ -15,7 +15,7 @@ fn old(_1: Result<T, E>) -> Result<T, E> { bb0: { _2 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16 - switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16 + switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16 } bb1: { diff --git a/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index 4aa5ba007f1..39ec0527759 100644 --- a/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -18,7 +18,7 @@ fn main() -> () { Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 _3 = discriminant(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 - switchInt(move _3) -> [2_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19 + switchInt(move _3) -> [2: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19 } bb1: { @@ -36,7 +36,7 @@ fn main() -> () { Deinit(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 discriminant(_7) = 0; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 _8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 - switchInt(move _8) -> [4_isize: bb5, 5_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 + switchInt(move _8) -> [4: bb5, 5: bb3, otherwise: bb4]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 } bb2: { diff --git a/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff index c3d356aedb2..598413a1d82 100644 --- a/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff @@ -19,8 +19,8 @@ Deinit(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 discriminant(_2) = 2; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 _3 = discriminant(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:11: +1:19 -- switchInt(move _3) -> [0_isize: bb3, 1_isize: bb4, 2_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19 -+ switchInt(move _3) -> [2_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19 +- switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19 ++ switchInt(move _3) -> [2: bb1, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+1:5: +1:19 } bb1: { @@ -65,7 +65,7 @@ Deinit(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 discriminant(_7) = 0; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 _8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 - switchInt(move _8) -> [4_isize: bb8, 5_isize: bb6, otherwise: bb7]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 + switchInt(move _8) -> [4: bb8, 5: bb6, otherwise: bb7]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 } bb6: { diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index ec5612ad767..c8cd6f6c1ea 100644 --- a/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -32,7 +32,7 @@ fn main() -> () { StorageLive(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 _4 = &(_1.1: Test1); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 _5 = discriminant((*_4)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 - switchInt(move _5) -> [2_isize: bb3, 3_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 + switchInt(move _5) -> [2: bb3, 3: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 } bb1: { @@ -66,7 +66,7 @@ fn main() -> () { StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7 StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6 _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 - switchInt(move _10) -> [2_isize: bb7, 3_isize: bb5, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 + switchInt(move _10) -> [2: bb7, 3: bb5, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 } bb5: { diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff index 77b358a4801..2aee6d2681d 100644 --- a/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff @@ -33,8 +33,8 @@ StorageLive(_4); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 _4 = &(_1.1: Test1); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 _5 = discriminant((*_4)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:11: +3:22 -- switchInt(move _5) -> [0_isize: bb3, 1_isize: bb4, 2_isize: bb5, 3_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 -+ switchInt(move _5) -> [2_isize: bb5, 3_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 +- switchInt(move _5) -> [0: bb3, 1: bb4, 2: bb5, 3: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 ++ switchInt(move _5) -> [2: bb5, 3: bb1, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+3:5: +3:22 } bb1: { @@ -87,8 +87,8 @@ StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7 StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6 _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 -- switchInt(move _10) -> [0_isize: bb9, 1_isize: bb10, 2_isize: bb11, 3_isize: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 -+ switchInt(move _10) -> [2_isize: bb11, 3_isize: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 +- switchInt(move _10) -> [0: bb9, 1: bb10, 2: bb11, 3: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 ++ switchInt(move _10) -> [2: bb11, 3: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 } bb7: { diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff index 11d93fca7e0..58e085dd041 100644 --- a/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff @@ -8,8 +8,8 @@ bb0: { _2 = discriminant(_1); // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:11: +1:12 -- switchInt(move _2) -> [1_isize: bb3, 2_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 -+ switchInt(move _2) -> [1_isize: bb3, 2_isize: bb2, otherwise: bb5]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 +- switchInt(move _2) -> [1: bb3, 2: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 ++ switchInt(move _2) -> [1: bb3, 2: bb2, otherwise: bb5]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 } bb1: { diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff index a7f8321ae34..e765851eb78 100644 --- a/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff @@ -8,8 +8,8 @@ bb0: { _2 = discriminant(_1); // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:11: +1:12 -- switchInt(move _2) -> [0_isize: bb2, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 -+ switchInt(move _2) -> [1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 +- switchInt(move _2) -> [0: bb2, 1: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 ++ switchInt(move _2) -> [1: bb3, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:+1:5: +1:12 } bb1: { diff --git a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff index 9cd4b8ccf33..848bff1d492 100644 --- a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff @@ -27,8 +27,8 @@ bb1: { _2 = discriminant(_1); // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 -- switchInt(move _2) -> [1_isize: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 -+ switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 +- switchInt(move _2) -> [1: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 ++ switchInt(move _2) -> [1: bb2, otherwise: bb3]; // scope 1 at $DIR/unreachable.rs:+1:12: +1:20 } bb2: { @@ -38,7 +38,7 @@ - StorageLive(_5); // scope 2 at $DIR/unreachable.rs:+4:9: +8:10 - StorageLive(_6); // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 - _6 = const true; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 -- switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 +- switchInt(move _6) -> [0: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 + unreachable; // scope 2 at $DIR/unreachable.rs:+4:12: +4:16 } diff --git a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff index afd6b00aac3..fb778470e53 100644 --- a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff @@ -29,7 +29,7 @@ bb1: { _3 = discriminant(_2); // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22 - switchInt(move _3) -> [1_isize: bb2, otherwise: bb6]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22 + switchInt(move _3) -> [1: bb2, otherwise: bb6]; // scope 2 at $DIR/unreachable_diverging.rs:+2:12: +2:22 } bb2: { @@ -38,7 +38,7 @@ StorageLive(_5); // scope 2 at $DIR/unreachable_diverging.rs:+3:9: +5:10 StorageLive(_6); // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 _6 = _1; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 - switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 + switchInt(move _6) -> [0: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable_diverging.rs:+3:12: +3:13 } bb3: { diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff index eef7011149d..984ef476e10 100644 --- a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff +++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff @@ -24,13 +24,13 @@ Deinit(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 discriminant(_3) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 - _4 = discriminant(_3); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 -- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 +- switchInt(move _4) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + _4 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 -+ switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 ++ switchInt(const 0_isize) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 } bb1: { - switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + switchInt(((_3 as Some).0: u32)) -> [0: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 } bb2: { diff --git a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir index 68aa3e5db32..1556c240dc5 100644 --- a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir +++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir @@ -24,7 +24,7 @@ fn while_loop(_1: bool) -> () { bb2: { StorageDead(_3); // scope 0 at $DIR/while_storage.rs:+1:21: +1:22 - switchInt(move _2) -> [false: bb7, otherwise: bb3]; // scope 0 at $DIR/while_storage.rs:+1:11: +1:22 + switchInt(move _2) -> [0: bb7, otherwise: bb3]; // scope 0 at $DIR/while_storage.rs:+1:11: +1:22 } bb3: { @@ -39,7 +39,7 @@ fn while_loop(_1: bool) -> () { bb4: { StorageDead(_5); // scope 0 at $DIR/while_storage.rs:+2:22: +2:23 - switchInt(move _4) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23 + switchInt(move _4) -> [0: bb6, otherwise: bb5]; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23 } bb5: { diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 2c4309fbe66..3aa57d58908 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -67,7 +67,7 @@ impl CodegenBackend for TheBackend { if crate_type != CrateType::Rlib { sess.fatal(&format!("Crate type is {:?}", crate_type)); } - let output_name = out_filename(sess, crate_type, &outputs, &*crate_name.as_str()); + let output_name = out_filename(sess, crate_type, &outputs, crate_name); let mut out_file = ::std::fs::File::create(output_name).unwrap(); write!(out_file, "This has been \"compiled\" successfully.").unwrap(); } diff --git a/src/test/run-make/coverage-reports/Makefile b/src/test/run-make/coverage-reports/Makefile index 436aebf1174..d06cd9c6a54 100644 --- a/src/test/run-make/coverage-reports/Makefile +++ b/src/test/run-make/coverage-reports/Makefile @@ -80,7 +80,7 @@ ifdef RUSTC_BLESS_TEST rm -f expected_* endif -include clear_expected_if_blessed +-include clear_expected_if_blessed %: $(SOURCEDIR)/lib/%.rs # Compile the test library with coverage instrumentation diff --git a/src/test/run-make/issue-71519/Makefile b/src/test/run-make/issue-71519/Makefile index 16d9a56e6bf..57497f52053 100644 --- a/src/test/run-make/issue-71519/Makefile +++ b/src/test/run-make/issue-71519/Makefile @@ -2,6 +2,7 @@ include ../../run-make-fulldeps/tools.mk # ignore-msvc # needs-rust-lld +# ignore-s390x lld does not yet support s390x as target all: RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Z gcc-ld=lld -C link-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt diff --git a/src/test/rustdoc-gui/basic.goml b/src/test/rustdoc-gui/basic.goml deleted file mode 100644 index 60292835bc0..00000000000 --- a/src/test/rustdoc-gui/basic.goml +++ /dev/null @@ -1,4 +0,0 @@ -goto: "file://" + |DOC_PATH| + "/test_docs/index.html" -assert: ("#functions") -goto: "./struct.Foo.html" -assert: ("div.item-decl") diff --git a/src/test/rustdoc-gui/docblock-table.goml b/src/test/rustdoc-gui/docblock-table.goml index 4e316ce0bcb..8645c1b1949 100644 --- a/src/test/rustdoc-gui/docblock-table.goml +++ b/src/test/rustdoc-gui/docblock-table.goml @@ -2,3 +2,50 @@ goto: "file://" + |DOC_PATH| + "/test_docs/doc_block_table/struct.DocBlockTable. compare-elements-css: (".impl-items .docblock table th", ".top-doc .docblock table th", ["border"]) compare-elements-css: (".impl-items .docblock table td", ".top-doc .docblock table td", ["border"]) + +define-function: ( + "check-colors", + (theme, border_color, zebra_stripe_color), + [ + ("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}), + ("reload"), + ("assert-css", (".top-doc .docblock table tbody tr:nth-child(1)", { + "background-color": "rgba(0, 0, 0, 0)", + })), + ("assert-css", (".top-doc .docblock table tbody tr:nth-child(2)", { + "background-color": |zebra_stripe_color|, + })), + ("assert-css", (".top-doc .docblock table tbody tr:nth-child(3)", { + "background-color": "rgba(0, 0, 0, 0)", + })), + ("assert-css", (".top-doc .docblock table tbody tr:nth-child(4)", { + "background-color": |zebra_stripe_color|, + })), + ("assert-css", (".top-doc .docblock table td", { + "border-style": "solid", + "border-width": "1px", + "border-color": |border_color|, + })), + ("assert-css", (".top-doc .docblock table th", { + "border-style": "solid", + "border-width": "1px", + "border-color": |border_color|, + })), + ] +) + +call-function: ("check-colors", { + "theme": "dark", + "border_color": "rgb(224, 224, 224)", + "zebra_stripe_color": "rgb(42, 42, 42)", +}) +call-function: ("check-colors", { + "theme": "ayu", + "border_color": "rgb(92, 103, 115)", + "zebra_stripe_color": "rgb(25, 31, 38)", +}) +call-function: ("check-colors", { + "theme": "light", + "border_color": "rgb(224, 224, 224)", + "zebra_stripe_color": "rgb(245, 245, 245)", +}) diff --git a/src/test/rustdoc-gui/scrape-examples-button-focus.goml b/src/test/rustdoc-gui/scrape-examples-button-focus.goml index a222139f1dc..bba518db099 100644 --- a/src/test/rustdoc-gui/scrape-examples-button-focus.goml +++ b/src/test/rustdoc-gui/scrape-examples-button-focus.goml @@ -1,5 +1,6 @@ goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html" +// The next/prev buttons vertically scroll the code viewport between examples store-property: (initialScrollTop, ".scraped-example-list > .scraped-example pre", "scrollTop") focus: ".scraped-example-list > .scraped-example .next" press-key: "Enter" @@ -12,6 +13,7 @@ assert-property: (".scraped-example-list > .scraped-example pre", { "scrollTop": |initialScrollTop| }) +// The expand button increases the scrollHeight of the minimized code viewport store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight") assert-property-false: (".scraped-example-list > .scraped-example pre", { "scrollHeight": |smallOffsetHeight| diff --git a/src/test/rustdoc-gui/scrape-examples-toggle.goml b/src/test/rustdoc-gui/scrape-examples-toggle.goml new file mode 100644 index 00000000000..ee720afb788 --- /dev/null +++ b/src/test/rustdoc-gui/scrape-examples-toggle.goml @@ -0,0 +1,14 @@ +goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html" + +// Clicking "More examples..." will open additional examples +assert-attribute-false: (".more-examples-toggle", {"open": ""}) +click: ".more-examples-toggle" +assert-attribute: (".more-examples-toggle", {"open": ""}) + +// Toggling all docs will close additional examples +click: "#toggle-all-docs" +assert-attribute-false: (".more-examples-toggle", {"open": ""}) + +// After re-opening the docs, the additional examples should stay closed +click: "#toggle-all-docs" +assert-attribute-false: (".more-examples-toggle", {"open": ""}) diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs index 1340511d472..d6eeab803df 100644 --- a/src/test/rustdoc-gui/src/test_docs/lib.rs +++ b/src/test/rustdoc-gui/src/test_docs/lib.rs @@ -343,6 +343,9 @@ pub mod doc_block_table { /// | header1 | header2 | /// |--------------------------|--------------------------| /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum | + /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum | + /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum | + /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum | pub struct DocBlockTable {} impl DocBlockTableTrait for DocBlockTable { diff --git a/src/test/rustdoc-gui/stab-badge.goml b/src/test/rustdoc-gui/stab-badge.goml new file mode 100644 index 00000000000..aaed8440a40 --- /dev/null +++ b/src/test/rustdoc-gui/stab-badge.goml @@ -0,0 +1,41 @@ +// All stability badges should have rounded corners and colored backgrounds. +goto: "file://" + |DOC_PATH| + "/test_docs/index.html" +show-text: true +define-function: ( + "check-badge", + (theme, background, color), + [ + ("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}), + ("goto", "file://" + |DOC_PATH| + "/test_docs/index.html"), + ("assert", (".docblock .stab")), + ("assert", (".item-table .stab")), + ("assert-css", (".stab", { + "border-radius": "3px", + "color": |color|, + "background-color": |background|, + })), + ("goto", "file://" + |DOC_PATH| + "/test_docs/fn.replaced_function.html"), + ("assert", (".item-info .stab")), + ("assert-css", (".stab", { + "border-radius": "3px", + "color": |color|, + "background-color": |background|, + })), + ] +) + +call-function: ("check-badge", { + "theme": "ayu", + "color": "rgb(197, 197, 197)", + "background": "rgb(49, 69, 89)", +}) +call-function: ("check-badge", { + "theme": "dark", + "color": "rgb(221, 221, 221)", + "background": "rgb(49, 69, 89)", +}) +call-function: ("check-badge", { + "theme": "light", + "color": "rgb(0, 0, 0)", + "background": "rgb(255, 245, 214)", +}) diff --git a/src/test/rustdoc/const-evalutation-ice.rs b/src/test/rustdoc-ui/const-evalutation-ice.rs index 68c7f9c5686..0dd3bcaa289 100644 --- a/src/test/rustdoc/const-evalutation-ice.rs +++ b/src/test/rustdoc-ui/const-evalutation-ice.rs @@ -7,4 +7,5 @@ pub struct S { s: Cell<usize> } -pub const N: usize = 0 - (mem::size_of::<S>() != 4) as usize; +pub const N: usize = 0 - (mem::size_of::<S>() != 400) as usize; +//~^ ERROR evaluation of constant value failed diff --git a/src/test/rustdoc-ui/const-evalutation-ice.stderr b/src/test/rustdoc-ui/const-evalutation-ice.stderr new file mode 100644 index 00000000000..5d9c16c0765 --- /dev/null +++ b/src/test/rustdoc-ui/const-evalutation-ice.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/const-evalutation-ice.rs:10:22 + | +LL | pub const N: usize = 0 - (mem::size_of::<S>() != 400) as usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/rustdoc-ui/doc-cfg.stderr b/src/test/rustdoc-ui/doc-cfg.stderr index b379f6febe2..14b7b17e04d 100644 --- a/src/test/rustdoc-ui/doc-cfg.stderr +++ b/src/test/rustdoc-ui/doc-cfg.stderr @@ -2,7 +2,7 @@ error: `cfg` predicate is not specified --> $DIR/doc-cfg.rs:3:7 | LL | #[doc(cfg(), cfg(foo, bar))] - | ^^^^^ + | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` error: multiple `cfg` predicates are specified --> $DIR/doc-cfg.rs:3:23 @@ -14,7 +14,7 @@ error: `cfg` predicate is not specified --> $DIR/doc-cfg.rs:7:7 | LL | #[doc(cfg())] - | ^^^^^ + | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` error: multiple `cfg` predicates are specified --> $DIR/doc-cfg.rs:8:16 diff --git a/src/test/ui/async-await/in-trait/nested-rpit.rs b/src/test/ui/async-await/in-trait/nested-rpit.rs new file mode 100644 index 00000000000..ae8e0aed0cc --- /dev/null +++ b/src/test/ui/async-await/in-trait/nested-rpit.rs @@ -0,0 +1,17 @@ +// check-pass +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::future::Future; +use std::marker::PhantomData; + +trait Lockable<K, V> { + async fn lock_all_entries(&self) -> impl Future<Output = Guard<'_>>; +} + +struct Guard<'a>(PhantomData<&'a ()>); + +fn main() {} diff --git a/src/test/ui/borrowck/issue-81899.stderr b/src/test/ui/borrowck/issue-81899.stderr index a4d5f212188..1b03bc3af9c 100644 --- a/src/test/ui/borrowck/issue-81899.stderr +++ b/src/test/ui/borrowck/issue-81899.stderr @@ -1,15 +1,19 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-81899.rs:11:5 | -LL | const _CONST: &[u8] = &f(&[], |_| {}); - | -------------- inside `_CONST` at $DIR/issue-81899.rs:4:24 -... +LL | panic!() + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-81899.rs:11:5 + | +note: inside `f::<[closure@$DIR/issue-81899.rs:4:31: 4:34]>` + --> $DIR/issue-81899.rs:11:5 + | LL | panic!() | ^^^^^^^^ - | | - | the evaluated program panicked at 'explicit panic', $DIR/issue-81899.rs:11:5 - | inside `f::<[closure@$DIR/issue-81899.rs:4:31: 4:34]>` at $SRC_DIR/std/src/panic.rs:LL:COL +note: inside `_CONST` + --> $DIR/issue-81899.rs:4:24 | +LL | const _CONST: &[u8] = &f(&[], |_| {}); + | ^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant used diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.stderr b/src/test/ui/borrowck/issue-88434-minimal-example.stderr index b95ddc49c99..a5a571c6d4d 100644 --- a/src/test/ui/borrowck/issue-88434-minimal-example.stderr +++ b/src/test/ui/borrowck/issue-88434-minimal-example.stderr @@ -1,15 +1,19 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-88434-minimal-example.rs:10:5 | -LL | const _CONST: &() = &f(&|_| {}); - | ---------- inside `_CONST` at $DIR/issue-88434-minimal-example.rs:3:22 -... +LL | panic!() + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:10:5 + | +note: inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:28]>` + --> $DIR/issue-88434-minimal-example.rs:10:5 + | LL | panic!() | ^^^^^^^^ - | | - | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:10:5 - | inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:28]>` at $SRC_DIR/std/src/panic.rs:LL:COL +note: inside `_CONST` + --> $DIR/issue-88434-minimal-example.rs:3:22 | +LL | const _CONST: &() = &f(&|_| {}); + | ^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant used diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr index 604a6577639..00023c459a8 100644 --- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr +++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr @@ -1,15 +1,19 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 | -LL | const _CONST: &[u8] = &f(&[], |_| {}); - | -------------- inside `_CONST` at $DIR/issue-88434-removal-index-should-be-less.rs:3:24 -... +LL | panic!() + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5 + | +note: inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34]>` + --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5 + | LL | panic!() | ^^^^^^^^ - | | - | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5 - | inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34]>` at $SRC_DIR/std/src/panic.rs:LL:COL +note: inside `_CONST` + --> $DIR/issue-88434-removal-index-should-be-less.rs:3:24 | +LL | const _CONST: &[u8] = &f(&[], |_| {}); + | ^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant used diff --git a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr index d4bd673b84e..d5b4349c00f 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-syntax-validation.stderr @@ -14,7 +14,7 @@ error: `cfg` predicate is not specified --> $DIR/cfg-attr-syntax-validation.rs:7:1 | LL | #[cfg()] - | ^^^^^^^^ + | ^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` error: multiple `cfg` predicates are specified --> $DIR/cfg-attr-syntax-validation.rs:10:10 diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-105257.rs b/src/test/ui/const-generics/generic_const_exprs/issue-105257.rs new file mode 100644 index 00000000000..d8b23bc01a9 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-105257.rs @@ -0,0 +1,9 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait Trait<T> { + fn fnc<const N: usize = "">(&self) {} //~ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + fn foo<const N: usize = { std::mem::size_of::<T>() }>(&self) {} //~ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +} + +fn main() {} diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-105257.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-105257.stderr new file mode 100644 index 00000000000..ed7a8cb19a4 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-105257.stderr @@ -0,0 +1,14 @@ +error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/issue-105257.rs:5:12 + | +LL | fn fnc<const N: usize = "">(&self) {} + | ^^^^^^^^^^^^^^^^^^^ + +error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/issue-105257.rs:6:12 + | +LL | fn foo<const N: usize = { std::mem::size_of::<T>() }>(&self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr index c90774e944f..029528c3a81 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-79518-default_trait_method_normalization.rs:16:32 | LL | Self::AssocInstance == [(); std::mem::size_of::<Self::Assoc>()]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found array `[(); _]` + | ------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found array `[(); _]` + | | + | expected because this is `<Self as Foo>::Assoc` | = note: expected associated type `<Self as Foo>::Assoc` found array `[(); _]` diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr index 1b502642eb7..bf1b411ee7c 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -2,15 +2,18 @@ error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | intrinsics::size_of::<T>() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | size_of called on unsized type `dyn Debug` - | inside `std::mem::size_of::<dyn Debug>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ size_of called on unsized type `dyn Debug` + | +note: inside `std::mem::size_of::<dyn Debug>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | - ::: $DIR/issue-80742.rs:22:10 +LL | intrinsics::size_of::<T>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `Inline::<dyn Debug>::{constant#0}` + --> $DIR/issue-80742.rs:22:10 | LL | [u8; size_of::<T>() + 1]: , - | -------------- inside `Inline::<dyn Debug>::{constant#0}` at $DIR/issue-80742.rs:22:10 + | ^^^^^^^^^^^^^^ error[E0599]: the function or associated item `new` exists for struct `Inline<dyn Debug>`, but its trait bounds were not satisfied --> $DIR/issue-80742.rs:30:36 @@ -33,15 +36,18 @@ error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | intrinsics::size_of::<T>() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | size_of called on unsized type `dyn Debug` - | inside `std::mem::size_of::<dyn Debug>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ size_of called on unsized type `dyn Debug` + | +note: inside `std::mem::size_of::<dyn Debug>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | - ::: $DIR/issue-80742.rs:14:10 +LL | intrinsics::size_of::<T>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `Inline::<dyn Debug>::{constant#0}` + --> $DIR/issue-80742.rs:14:10 | LL | [u8; size_of::<T>() + 1]: , - | -------------- inside `Inline::<dyn Debug>::{constant#0}` at $DIR/issue-80742.rs:14:10 + | ^^^^^^^^^^^^^^ error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time --> $DIR/issue-80742.rs:30:15 diff --git a/src/test/ui/const-generics/issues/issue-100313.stderr b/src/test/ui/const-generics/issues/issue-100313.stderr index f3ce357c2bb..d4b486376ca 100644 --- a/src/test/ui/const-generics/issues/issue-100313.stderr +++ b/src/test/ui/const-generics/issues/issue-100313.stderr @@ -2,13 +2,18 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-100313.rs:10:13 | LL | *(B as *const bool as *mut bool) = false; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to alloc7 which is read-only + | +note: inside `T::<&true>::set_false` + --> $DIR/issue-100313.rs:10:13 + | +LL | *(B as *const bool as *mut bool) = false; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | writing to alloc7 which is read-only - | inside `T::<&true>::set_false` at $DIR/issue-100313.rs:10:13 -... +note: inside `_` + --> $DIR/issue-100313.rs:18:5 + | LL | x.set_false(); - | ------------- inside `_` at $DIR/issue-100313.rs:18:5 + | ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr index 8978ab436d0..563f3ffd674 100644 --- a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr +++ b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr @@ -2,43 +2,52 @@ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | LL | &*ptr::slice_from_raw_parts(data, len) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) - | inside `std::slice::from_raw_parts::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | +note: inside `std::slice::from_raw_parts::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:18:34 +LL | &*ptr::slice_from_raw_parts(data, len) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `S0` + --> $DIR/forbidden_slices.rs:18:34 | LL | pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) }; - | ------------------------------ inside `S0` at $DIR/forbidden_slices.rs:18:34 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | LL | &*ptr::slice_from_raw_parts(data, len) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) - | inside `std::slice::from_raw_parts::<'_, ()>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | +note: inside `std::slice::from_raw_parts::<'_, ()>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:19:33 +LL | &*ptr::slice_from_raw_parts(data, len) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `S1` + --> $DIR/forbidden_slices.rs:19:33 | LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) }; - | ------------------------------ inside `S1` at $DIR/forbidden_slices.rs:19:33 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | LL | &*ptr::slice_from_raw_parts(data, len) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds - | inside `std::slice::from_raw_parts::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + | +note: inside `std::slice::from_raw_parts::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:22:34 +LL | &*ptr::slice_from_raw_parts(data, len) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `S2` + --> $DIR/forbidden_slices.rs:22:34 | LL | pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) }; - | ---------------------- inside `S2` at $DIR/forbidden_slices.rs:22:34 + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/forbidden_slices.rs:25:1 @@ -89,72 +98,85 @@ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | LL | &*ptr::slice_from_raw_parts(data, len) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds - | inside `std::slice::from_raw_parts::<'_, u64>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds | - ::: $DIR/forbidden_slices.rs:43:5 +note: inside `std::slice::from_raw_parts::<'_, u64>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL + | +LL | &*ptr::slice_from_raw_parts(data, len) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `S8` + --> $DIR/forbidden_slices.rs:43:5 | LL | from_raw_parts(ptr, 1) - | ---------------------- inside `S8` at $DIR/forbidden_slices.rs:43:5 + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance) - | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance) | - ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } - | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL +LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `from_ptr_range::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:46:34 +LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R0` + --> $DIR/forbidden_slices.rs:46:34 | LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; - | ---------------------------------------- inside `R0` at $DIR/forbidden_slices.rs:46:34 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `ptr::const_ptr::<impl *const ()>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const ()>::sub_ptr` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } - | ------------------------------ inside `from_ptr_range::<'_, ()>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL +LL | assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `from_ptr_range::<'_, ()>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:47:33 +LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R1` + --> $DIR/forbidden_slices.rs:47:33 | LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; - | ---------------------------------------- inside `R1` at $DIR/forbidden_slices.rs:47:33 - | + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + | +note: inside `ptr::const_ptr::<impl *const u32>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds - | inside `ptr::const_ptr::<impl *const u32>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -... -LL | unsafe { self.offset(count as isize) } - | --------------------------- inside `ptr::const_ptr::<impl *const u32>::add` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u32>::add` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:50:25 +LL | unsafe { self.offset(count as isize) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R2` + --> $DIR/forbidden_slices.rs:50:25 | LL | from_ptr_range(ptr..ptr.add(2)) - | ---------- inside `R2` at $DIR/forbidden_slices.rs:50:25 + | ^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/forbidden_slices.rs:52:1 @@ -205,56 +227,67 @@ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds + | +note: inside `ptr::const_ptr::<impl *const u64>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds - | inside `ptr::const_ptr::<impl *const u64>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -... -LL | unsafe { self.offset(count as isize) } - | --------------------------- inside `ptr::const_ptr::<impl *const u64>::add` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u64>::add` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:74:25 +LL | unsafe { self.offset(count as isize) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R8` + --> $DIR/forbidden_slices.rs:74:25 | LL | from_ptr_range(ptr..ptr.add(1)) - | ---------- inside `R8` at $DIR/forbidden_slices.rs:74:25 + | ^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `ptr_offset_from_unsigned` called on pointers into different allocations - | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations | - ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } - | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL +LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `from_ptr_range::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:79:34 +LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R9` + --> $DIR/forbidden_slices.rs:79:34 | LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) }; - | ----------------------------------------------- inside `R9` at $DIR/forbidden_slices.rs:79:34 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `ptr_offset_from_unsigned` called on pointers into different allocations - | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations | - ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } - | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL +LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `from_ptr_range::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:80:35 +LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R10` + --> $DIR/forbidden_slices.rs:80:35 | LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) }; - | ------------------------ inside `R10` at $DIR/forbidden_slices.rs:80:35 + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 18 previous errors diff --git a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr index db42b7c9830..43529d57f40 100644 --- a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr +++ b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr @@ -2,43 +2,52 @@ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | LL | &*ptr::slice_from_raw_parts(data, len) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) - | inside `std::slice::from_raw_parts::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | +note: inside `std::slice::from_raw_parts::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:18:34 +LL | &*ptr::slice_from_raw_parts(data, len) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `S0` + --> $DIR/forbidden_slices.rs:18:34 | LL | pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) }; - | ------------------------------ inside `S0` at $DIR/forbidden_slices.rs:18:34 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | LL | &*ptr::slice_from_raw_parts(data, len) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) - | inside `std::slice::from_raw_parts::<'_, ()>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | +note: inside `std::slice::from_raw_parts::<'_, ()>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:19:33 +LL | &*ptr::slice_from_raw_parts(data, len) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `S1` + --> $DIR/forbidden_slices.rs:19:33 | LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) }; - | ------------------------------ inside `S1` at $DIR/forbidden_slices.rs:19:33 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | LL | &*ptr::slice_from_raw_parts(data, len) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds - | inside `std::slice::from_raw_parts::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + | +note: inside `std::slice::from_raw_parts::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:22:34 +LL | &*ptr::slice_from_raw_parts(data, len) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `S2` + --> $DIR/forbidden_slices.rs:22:34 | LL | pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) }; - | ---------------------- inside `S2` at $DIR/forbidden_slices.rs:22:34 + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/forbidden_slices.rs:25:1 @@ -89,72 +98,85 @@ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | LL | &*ptr::slice_from_raw_parts(data, len) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds - | inside `std::slice::from_raw_parts::<'_, u64>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds | - ::: $DIR/forbidden_slices.rs:43:5 +note: inside `std::slice::from_raw_parts::<'_, u64>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL + | +LL | &*ptr::slice_from_raw_parts(data, len) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `S8` + --> $DIR/forbidden_slices.rs:43:5 | LL | from_raw_parts(ptr, 1) - | ---------------------- inside `S8` at $DIR/forbidden_slices.rs:43:5 + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance) - | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance) | - ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } - | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL +LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `from_ptr_range::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:46:34 +LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R0` + --> $DIR/forbidden_slices.rs:46:34 | LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; - | ---------------------------------------- inside `R0` at $DIR/forbidden_slices.rs:46:34 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `ptr::const_ptr::<impl *const ()>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const ()>::sub_ptr` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } - | ------------------------------ inside `from_ptr_range::<'_, ()>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL +LL | assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `from_ptr_range::<'_, ()>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:47:33 +LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R1` + --> $DIR/forbidden_slices.rs:47:33 | LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; - | ---------------------------------------- inside `R1` at $DIR/forbidden_slices.rs:47:33 - | + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + | +note: inside `ptr::const_ptr::<impl *const u32>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds - | inside `ptr::const_ptr::<impl *const u32>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -... -LL | unsafe { self.offset(count as isize) } - | --------------------------- inside `ptr::const_ptr::<impl *const u32>::add` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u32>::add` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:50:25 +LL | unsafe { self.offset(count as isize) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R2` + --> $DIR/forbidden_slices.rs:50:25 | LL | from_ptr_range(ptr..ptr.add(2)) - | ---------- inside `R2` at $DIR/forbidden_slices.rs:50:25 + | ^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/forbidden_slices.rs:52:1 @@ -205,56 +227,67 @@ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds + | +note: inside `ptr::const_ptr::<impl *const u64>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds - | inside `ptr::const_ptr::<impl *const u64>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -... -LL | unsafe { self.offset(count as isize) } - | --------------------------- inside `ptr::const_ptr::<impl *const u64>::add` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u64>::add` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:74:25 +LL | unsafe { self.offset(count as isize) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R8` + --> $DIR/forbidden_slices.rs:74:25 | LL | from_ptr_range(ptr..ptr.add(1)) - | ---------- inside `R8` at $DIR/forbidden_slices.rs:74:25 + | ^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `ptr_offset_from_unsigned` called on pointers into different allocations - | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations | - ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } - | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL +LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `from_ptr_range::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:79:34 +LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R9` + --> $DIR/forbidden_slices.rs:79:34 | LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) }; - | ----------------------------------------------- inside `R9` at $DIR/forbidden_slices.rs:79:34 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `ptr_offset_from_unsigned` called on pointers into different allocations - | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations | - ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } - | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL +LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `from_ptr_range::<'_, u32>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - ::: $DIR/forbidden_slices.rs:80:35 +LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `R10` + --> $DIR/forbidden_slices.rs:80:35 | LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) }; - | ------------------------ inside `R10` at $DIR/forbidden_slices.rs:80:35 + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 18 previous errors diff --git a/src/test/ui/const-ptr/out_of_bounds_read.stderr b/src/test/ui/const-ptr/out_of_bounds_read.stderr index 52b173c4d04..bca29b46881 100644 --- a/src/test/ui/const-ptr/out_of_bounds_read.stderr +++ b/src/test/ui/const-ptr/out_of_bounds_read.stderr @@ -2,53 +2,62 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds - | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + | +note: inside `std::ptr::read::<u32>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - ::: $DIR/out_of_bounds_read.rs:12:33 +LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `_READ` + --> $DIR/out_of_bounds_read.rs:12:33 | LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) }; - | ----------------------- inside `_READ` at $DIR/out_of_bounds_read.rs:12:33 + | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds - | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | - ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `std::ptr::read::<u32>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | -LL | unsafe { read(self) } - | ---------- inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `ptr::const_ptr::<impl *const u32>::read` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/out_of_bounds_read.rs:13:39 +LL | unsafe { read(self) } + | ^^^^^^^^^^ +note: inside `_CONST_READ` + --> $DIR/out_of_bounds_read.rs:13:39 | LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() }; - | ------------------- inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:13:39 + | ^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds - | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + | +note: inside `std::ptr::read::<u32>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - ::: $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL +LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `ptr::mut_ptr::<impl *mut u32>::read` + --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL | LL | unsafe { read(self) } - | ---------- inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - | - ::: $DIR/out_of_bounds_read.rs:14:37 + | ^^^^^^^^^^ +note: inside `_MUT_READ` + --> $DIR/out_of_bounds_read.rs:14:37 | LL | const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() }; - | --------------------------------- inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:14:37 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index 3784a3861c3..0734f479f98 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -2,25 +2,35 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_fn_ptr_fail2.rs:9:5 | LL | x(y) + | ^^^^ calling non-const function `double` + | +note: inside `bar` + --> $DIR/const_fn_ptr_fail2.rs:9:5 + | +LL | x(y) | ^^^^ - | | - | calling non-const function `double` - | inside `bar` at $DIR/const_fn_ptr_fail2.rs:9:5 -... +note: inside `Y` + --> $DIR/const_fn_ptr_fail2.rs:14:18 + | LL | const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday - | --------- inside `Y` at $DIR/const_fn_ptr_fail2.rs:14:18 + | ^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $DIR/const_fn_ptr_fail2.rs:9:5 | LL | x(y) + | ^^^^ calling non-const function `double` + | +note: inside `bar` + --> $DIR/const_fn_ptr_fail2.rs:9:5 + | +LL | x(y) | ^^^^ - | | - | calling non-const function `double` - | inside `bar` at $DIR/const_fn_ptr_fail2.rs:9:5 -... +note: inside `Z` + --> $DIR/const_fn_ptr_fail2.rs:15:18 + | LL | const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday - | -------------- inside `Z` at $DIR/const_fn_ptr_fail2.rs:15:18 + | ^^^^^^^^^^^^^^ warning: skipping const checks | diff --git a/src/test/ui/consts/const-eval/const_panic_track_caller.stderr b/src/test/ui/consts/const-eval/const_panic_track_caller.stderr index 5c3b412d37f..846458176d6 100644 --- a/src/test/ui/consts/const-eval/const_panic_track_caller.stderr +++ b/src/test/ui/consts/const-eval/const_panic_track_caller.stderr @@ -2,13 +2,18 @@ error[E0080]: evaluation of constant value failed --> $DIR/const_panic_track_caller.rs:15:5 | LL | b() + | ^^^ the evaluated program panicked at 'hey', $DIR/const_panic_track_caller.rs:15:5 + | +note: inside `c` + --> $DIR/const_panic_track_caller.rs:15:5 + | +LL | b() | ^^^ - | | - | the evaluated program panicked at 'hey', $DIR/const_panic_track_caller.rs:15:5 - | inside `c` at $DIR/const_panic_track_caller.rs:15:5 -... +note: inside `X` + --> $DIR/const_panic_track_caller.rs:21:16 + | LL | const X: u32 = c(); - | --- inside `X` at $DIR/const_panic_track_caller.rs:21:16 + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr index 2628a78455c..8f3b3d5f700 100644 --- a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr +++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr @@ -1,14 +1,19 @@ error[E0080]: evaluation of constant value failed --> $DIR/alloc_intrinsic_errors.rs:9:17 | -LL | const FOO: i32 = foo(); - | ----- inside `FOO` at $DIR/alloc_intrinsic_errors.rs:6:18 -... +LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ align has to be a power of 2, `3` is not a power of 2 + | +note: inside `foo` + --> $DIR/alloc_intrinsic_errors.rs:9:17 + | LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | align has to be a power of 2, `3` is not a power of 2 - | inside `foo` at $DIR/alloc_intrinsic_errors.rs:9:17 +note: inside `FOO` + --> $DIR/alloc_intrinsic_errors.rs:6:18 + | +LL | const FOO: i32 = foo(); + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/unwind-abort.stderr b/src/test/ui/consts/const-eval/unwind-abort.stderr index 99178ae8c83..759ce15ab1b 100644 --- a/src/test/ui/consts/const-eval/unwind-abort.stderr +++ b/src/test/ui/consts/const-eval/unwind-abort.stderr @@ -2,14 +2,18 @@ error[E0080]: evaluation of constant value failed --> $DIR/unwind-abort.rs:4:5 | LL | panic!() + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:4:5 + | +note: inside `foo` + --> $DIR/unwind-abort.rs:4:5 + | +LL | panic!() | ^^^^^^^^ - | | - | the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:4:5 - | inside `foo` at $SRC_DIR/std/src/panic.rs:LL:COL -... -LL | const _: () = foo(); - | ----- inside `_` at $DIR/unwind-abort.rs:7:15 +note: inside `_` + --> $DIR/unwind-abort.rs:7:15 | +LL | const _: () = foo(); + | ^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr index 8b4d845b30e..9710bf476ec 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr @@ -14,13 +14,18 @@ error[E0080]: evaluation of constant value failed --> $DIR/validate_uninhabited_zsts.rs:4:14 | LL | unsafe { std::mem::transmute(()) } + | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type + | +note: inside `foo` + --> $DIR/validate_uninhabited_zsts.rs:4:14 + | +LL | unsafe { std::mem::transmute(()) } | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | transmuting to uninhabited type - | inside `foo` at $DIR/validate_uninhabited_zsts.rs:4:14 -... +note: inside `FOO` + --> $DIR/validate_uninhabited_zsts.rs:19:33 + | LL | const FOO: [empty::Empty; 3] = [foo(); 3]; - | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:19:33 + | ^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/validate_uninhabited_zsts.rs:21:1 diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr index 8b4d845b30e..9710bf476ec 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr @@ -14,13 +14,18 @@ error[E0080]: evaluation of constant value failed --> $DIR/validate_uninhabited_zsts.rs:4:14 | LL | unsafe { std::mem::transmute(()) } + | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type + | +note: inside `foo` + --> $DIR/validate_uninhabited_zsts.rs:4:14 + | +LL | unsafe { std::mem::transmute(()) } | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | transmuting to uninhabited type - | inside `foo` at $DIR/validate_uninhabited_zsts.rs:4:14 -... +note: inside `FOO` + --> $DIR/validate_uninhabited_zsts.rs:19:33 + | LL | const FOO: [empty::Empty; 3] = [foo(); 3]; - | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:19:33 + | ^^^^^ error[E0080]: it is undefined behavior to use this value --> $DIR/validate_uninhabited_zsts.rs:21:1 diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr index e1ad72416f2..195a087ffa5 100644 --- a/src/test/ui/consts/const-float-bits-reject-conv.stderr +++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr @@ -2,38 +2,46 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/num/f32.rs:LL:COL | LL | panic!("const-eval error: cannot use f32::to_bits on a NaN") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL + | +note: inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32` + --> $SRC_DIR/core/src/num/f32.rs:LL:COL + | +LL | panic!("const-eval error: cannot use f32::to_bits on a NaN") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL - | inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32` at $SRC_DIR/core/src/panic.rs:LL:COL -... -LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } - | -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL +note: inside `core::f32::<impl f32>::to_bits` + --> $SRC_DIR/core/src/num/f32.rs:LL:COL | - ::: $DIR/const-float-bits-reject-conv.rs:28:30 +LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `f32::MASKED_NAN1` + --> $DIR/const-float-bits-reject-conv.rs:28:30 | LL | const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA; - | ------------------ inside `f32::MASKED_NAN1` at $DIR/const-float-bits-reject-conv.rs:28:30 - | + | ^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/num/f32.rs:LL:COL | LL | panic!("const-eval error: cannot use f32::to_bits on a NaN") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL + | +note: inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32` + --> $SRC_DIR/core/src/num/f32.rs:LL:COL + | +LL | panic!("const-eval error: cannot use f32::to_bits on a NaN") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL - | inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32` at $SRC_DIR/core/src/panic.rs:LL:COL -... -LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } - | -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL +note: inside `core::f32::<impl f32>::to_bits` + --> $SRC_DIR/core/src/num/f32.rs:LL:COL | - ::: $DIR/const-float-bits-reject-conv.rs:30:30 +LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `f32::MASKED_NAN2` + --> $DIR/const-float-bits-reject-conv.rs:30:30 | LL | const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555; - | ------------------ inside `f32::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:30:30 - | + | ^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant used @@ -64,38 +72,46 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/num/f64.rs:LL:COL | LL | panic!("const-eval error: cannot use f64::to_bits on a NaN") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL + | +note: inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64` + --> $SRC_DIR/core/src/num/f64.rs:LL:COL + | +LL | panic!("const-eval error: cannot use f64::to_bits on a NaN") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL - | inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64` at $SRC_DIR/core/src/panic.rs:LL:COL -... -LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) } - | -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL +note: inside `core::f64::<impl f64>::to_bits` + --> $SRC_DIR/core/src/num/f64.rs:LL:COL | - ::: $DIR/const-float-bits-reject-conv.rs:50:30 +LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `f64::MASKED_NAN1` + --> $DIR/const-float-bits-reject-conv.rs:50:30 | LL | const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; - | ------------------ inside `f64::MASKED_NAN1` at $DIR/const-float-bits-reject-conv.rs:50:30 - | + | ^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/num/f64.rs:LL:COL | LL | panic!("const-eval error: cannot use f64::to_bits on a NaN") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL + | +note: inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64` + --> $SRC_DIR/core/src/num/f64.rs:LL:COL + | +LL | panic!("const-eval error: cannot use f64::to_bits on a NaN") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL - | inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64` at $SRC_DIR/core/src/panic.rs:LL:COL -... -LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) } - | -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL +note: inside `core::f64::<impl f64>::to_bits` + --> $SRC_DIR/core/src/num/f64.rs:LL:COL | - ::: $DIR/const-float-bits-reject-conv.rs:52:30 +LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `f64::MASKED_NAN2` + --> $DIR/const-float-bits-reject-conv.rs:52:30 | LL | const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; - | ------------------ inside `f64::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:52:30 - | + | ^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant used diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr index 234e55e3a96..6e110dbdd64 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr @@ -2,13 +2,18 @@ error[E0080]: evaluation of constant value failed --> $DIR/mut_ref_in_final_dynamic_check.rs:13:10 | LL | Some(&mut *(42 as *mut i32)) + | ^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2a[noalloc] is a dangling pointer (it has no provenance) + | +note: inside `helper` + --> $DIR/mut_ref_in_final_dynamic_check.rs:13:10 + | +LL | Some(&mut *(42 as *mut i32)) | ^^^^^^^^^^^^^^^^^^^^^^ - | | - | dereferencing pointer failed: 0x2a[noalloc] is a dangling pointer (it has no provenance) - | inside `helper` at $DIR/mut_ref_in_final_dynamic_check.rs:13:10 -... +note: inside `A` + --> $DIR/mut_ref_in_final_dynamic_check.rs:18:29 + | LL | const A: Option<&mut i32> = helper(); - | -------- inside `A` at $DIR/mut_ref_in_final_dynamic_check.rs:18:29 + | ^^^^^^^^ error: encountered dangling pointer in final constant --> $DIR/mut_ref_in_final_dynamic_check.rs:25:1 diff --git a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr index f6de3699f77..cbc7cac937a 100644 --- a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr +++ b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr @@ -2,18 +2,23 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/hint.rs:LL:COL | LL | intrinsics::unreachable() - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | entering unreachable code - | inside `unreachable_unchecked` at $SRC_DIR/core/src/hint.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^ entering unreachable code + | +note: inside `unreachable_unchecked` + --> $SRC_DIR/core/src/hint.rs:LL:COL | - ::: $DIR/const_unsafe_unreachable_ub.rs:6:18 +LL | intrinsics::unreachable() + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `foo` + --> $DIR/const_unsafe_unreachable_ub.rs:6:18 | LL | false => std::hint::unreachable_unchecked(), - | ---------------------------------- inside `foo` at $DIR/const_unsafe_unreachable_ub.rs:6:18 -... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `BAR` + --> $DIR/const_unsafe_unreachable_ub.rs:10:28 + | LL | const BAR: bool = unsafe { foo(false) }; - | ---------- inside `BAR` at $DIR/const_unsafe_unreachable_ub.rs:10:28 + | ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index 4726905ade3..2603a73583e 100644 --- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -32,20 +32,23 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | accessing memory with alignment 1, but alignment 4 is required - | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment 1, but alignment 4 is required | - ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `std::ptr::read::<u32>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | -LL | unsafe { read(self) } - | ---------- inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `ptr::const_ptr::<impl *const u32>::read` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/detect-extra-ub.rs:38:9 +LL | unsafe { read(self) } + | ^^^^^^^^^^ +note: inside `INNER` + --> $DIR/detect-extra-ub.rs:38:9 | LL | ptr.read(); - | ---------- inside `INNER` at $DIR/detect-extra-ub.rs:38:9 + | ^^^^^^^^^^ note: erroneous constant used --> $DIR/detect-extra-ub.rs:32:5 diff --git a/src/test/ui/consts/issue-miri-1910.stderr b/src/test/ui/consts/issue-miri-1910.stderr index 3872e3d4f0d..1f82e1777af 100644 --- a/src/test/ui/consts/issue-miri-1910.stderr +++ b/src/test/ui/consts/issue-miri-1910.stderr @@ -2,23 +2,25 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | unable to copy parts of a pointer from memory at ALLOC - | inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to copy parts of a pointer from memory at ALLOC | - ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + = help: this code performed an operation that depends on the underlying bytes representing a pointer + = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported +note: inside `std::ptr::read::<u8>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | -LL | unsafe { read(self) } - | ---------- inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `ptr::const_ptr::<impl *const u8>::read` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/issue-miri-1910.rs:8:5 +LL | unsafe { read(self) } + | ^^^^^^^^^^ +note: inside `C` + --> $DIR/issue-miri-1910.rs:8:5 | LL | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read(); - | ------------------------------------------------------------------- inside `C` at $DIR/issue-miri-1910.rs:8:5 - | - = help: this code performed an operation that depends on the underlying bytes representing a pointer - = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr b/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr index 840d698ebbf..cf3fd88d034 100644 --- a/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr +++ b/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr @@ -2,13 +2,18 @@ error[E0080]: could not evaluate static initializer --> $DIR/abi-mismatch.rs:9:5 | LL | my_fn(); + | ^^^^^^^ calling a function with calling convention C using calling convention Rust + | +note: inside `call_rust_fn` + --> $DIR/abi-mismatch.rs:9:5 + | +LL | my_fn(); | ^^^^^^^ - | | - | calling a function with calling convention C using calling convention Rust - | inside `call_rust_fn` at $DIR/abi-mismatch.rs:9:5 -... +note: inside `VAL` + --> $DIR/abi-mismatch.rs:15:18 + | LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) }); - | --------------------------------------------------------------------- inside `VAL` at $DIR/abi-mismatch.rs:15:18 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: skipping const checks | diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.stderr b/src/test/ui/consts/miri_unleashed/assoc_const.stderr index 33e7e4af276..b26f121dba0 100644 --- a/src/test/ui/consts/miri_unleashed/assoc_const.stderr +++ b/src/test/ui/consts/miri_unleashed/assoc_const.stderr @@ -2,16 +2,23 @@ error[E0080]: evaluation of `<std::string::String as Bar<std::vec::Vec<u32>, std --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `<Vec<u32> as Drop>::drop` + | +note: inside `std::ptr::drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | +LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | calling non-const function `<Vec<u32> as Drop>::drop` - | inside `std::ptr::drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | inside `std::ptr::drop_in_place::<(Vec<u32>, u32)> - shim(Some((Vec<u32>, u32)))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `std::ptr::drop_in_place::<(Vec<u32>, u32)> - shim(Some((Vec<u32>, u32)))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - ::: $DIR/assoc_const.rs:12:31 +LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `<String as Bar<Vec<u32>, String>>::F` + --> $DIR/assoc_const.rs:12:31 | LL | const F: u32 = (U::X, 42).1; - | - inside `<String as Bar<Vec<u32>, String>>::F` at $DIR/assoc_const.rs:12:31 + | ^ note: erroneous constant used --> $DIR/assoc_const.rs:29:13 diff --git a/src/test/ui/consts/miri_unleashed/drop.stderr b/src/test/ui/consts/miri_unleashed/drop.stderr index a3a502723d2..e2e2f16d5a0 100644 --- a/src/test/ui/consts/miri_unleashed/drop.stderr +++ b/src/test/ui/consts/miri_unleashed/drop.stderr @@ -2,15 +2,18 @@ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | calling non-const function `<Vec<i32> as Drop>::drop` - | inside `std::ptr::drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `<Vec<i32> as Drop>::drop` + | +note: inside `std::ptr::drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - ::: $DIR/drop.rs:17:1 +LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `TEST_BAD` + --> $DIR/drop.rs:17:1 | LL | }; - | - inside `TEST_BAD` at $DIR/drop.rs:17:1 + | ^ warning: skipping const checks | diff --git a/src/test/ui/consts/missing_span_in_backtrace.rs b/src/test/ui/consts/missing_span_in_backtrace.rs new file mode 100644 index 00000000000..c4930b73aaa --- /dev/null +++ b/src/test/ui/consts/missing_span_in_backtrace.rs @@ -0,0 +1,27 @@ +// compile-flags: -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ui-testing=no +// normalize-stderr-test "alloc[0-9]+" -> "ALLOC_ID" + +#![feature(const_swap)] +#![feature(const_mut_refs)] +use std::{ + mem::{self, MaybeUninit}, + ptr, +}; + +const X: () = { + let mut ptr1 = &1; + let mut ptr2 = &2; + + // Swap them, bytewise. + unsafe { + ptr::swap_nonoverlapping( + &mut ptr1 as *mut _ as *mut MaybeUninit<u8>, + &mut ptr2 as *mut _ as *mut MaybeUninit<u8>, + mem::size_of::<&i32>(), + ); + } +}; + +fn main() { + X +} diff --git a/src/test/ui/consts/missing_span_in_backtrace.stderr b/src/test/ui/consts/missing_span_in_backtrace.stderr new file mode 100644 index 00000000000..e6d3d51990d --- /dev/null +++ b/src/test/ui/consts/missing_span_in_backtrace.stderr @@ -0,0 +1,28 @@ +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | + = note: unable to copy parts of a pointer from memory at ALLOC_ID + | + = help: this code performed an operation that depends on the underlying bytes representing a pointer + = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported +note: inside `std::ptr::read::<MaybeUninit<MaybeUninit<u8>>>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `mem::swap_simple::<MaybeUninit<MaybeUninit<u8>>>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +note: inside `ptr::swap_nonoverlapping_simple_untyped::<MaybeUninit<u8>>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `swap_nonoverlapping::<MaybeUninit<u8>>` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `X` + --> $DIR/missing_span_in_backtrace.rs:17:9 + | +17 | / ptr::swap_nonoverlapping( +18 | | &mut ptr1 as *mut _ as *mut MaybeUninit<u8>, +19 | | &mut ptr2 as *mut _ as *mut MaybeUninit<u8>, +20 | | mem::size_of::<&i32>(), +21 | | ); + | |_________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/offset_from_ub.stderr b/src/test/ui/consts/offset_from_ub.stderr index 62a087d94d3..9578d90ea9d 100644 --- a/src/test/ui/consts/offset_from_ub.stderr +++ b/src/test/ui/consts/offset_from_ub.stderr @@ -8,15 +8,18 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::ptr_offset_from(self, origin) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `ptr_offset_from` called on pointers into different allocations - | inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on pointers into different allocations + | +note: inside `ptr::const_ptr::<impl *const u8>::offset_from` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/offset_from_ub.rs:24:14 +LL | unsafe { intrinsics::ptr_offset_from(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `NOT_PTR` + --> $DIR/offset_from_ub.rs:24:14 | LL | unsafe { (42 as *const u8).offset_from(&5u8) as usize } - | ----------------------------------- inside `NOT_PTR` at $DIR/offset_from_ub.rs:24:14 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:31:14 @@ -88,29 +91,35 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::ptr_offset_from(self, origin) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance) - | inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance) | - ::: $DIR/offset_from_ub.rs:115:14 +note: inside `ptr::const_ptr::<impl *const u8>::offset_from` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::ptr_offset_from(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `OFFSET_VERY_FAR1` + --> $DIR/offset_from_ub.rs:115:14 | LL | unsafe { ptr2.offset_from(ptr1) } - | ---------------------- inside `OFFSET_VERY_FAR1` at $DIR/offset_from_ub.rs:115:14 + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::ptr_offset_from(self, origin) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance) - | inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance) | - ::: $DIR/offset_from_ub.rs:121:14 +note: inside `ptr::const_ptr::<impl *const u8>::offset_from` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::ptr_offset_from(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `OFFSET_VERY_FAR2` + --> $DIR/offset_from_ub.rs:121:14 | LL | unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) } - | ----------------------------------------- inside `OFFSET_VERY_FAR2` at $DIR/offset_from_ub.rs:121:14 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 15 previous errors diff --git a/src/test/ui/consts/offset_ub.stderr b/src/test/ui/consts/offset_ub.stderr index 5a792bba50c..7938f70a269 100644 --- a/src/test/ui/consts/offset_ub.stderr +++ b/src/test/ui/consts/offset_ub.stderr @@ -2,169 +2,205 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | overflowing in-bounds pointer arithmetic - | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic + | +note: inside `ptr::const_ptr::<impl *const u8>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/offset_ub.rs:7:46 +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `BEFORE_START` + --> $DIR/offset_ub.rs:7:46 | LL | pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; - | ------------------------------ inside `BEFORE_START` at $DIR/offset_ub.rs:7:46 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: allocN has size 1, so pointer to 2 bytes starting at offset 0 is out-of-bounds - | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: allocN has size 1, so pointer to 2 bytes starting at offset 0 is out-of-bounds | - ::: $DIR/offset_ub.rs:8:43 +note: inside `ptr::const_ptr::<impl *const u8>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `AFTER_END` + --> $DIR/offset_ub.rs:8:43 | LL | pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) }; - | ----------------------------- inside `AFTER_END` at $DIR/offset_ub.rs:8:43 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: allocN has size 100, so pointer to 101 bytes starting at offset 0 is out-of-bounds - | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: allocN has size 100, so pointer to 101 bytes starting at offset 0 is out-of-bounds | - ::: $DIR/offset_ub.rs:9:45 +note: inside `ptr::const_ptr::<impl *const u8>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `AFTER_ARRAY` + --> $DIR/offset_ub.rs:9:45 | LL | pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) }; - | ------------------------------- inside `AFTER_ARRAY` at $DIR/offset_ub.rs:9:45 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | overflowing in-bounds pointer arithmetic - | inside `ptr::const_ptr::<impl *const u16>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic + | +note: inside `ptr::const_ptr::<impl *const u16>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/offset_ub.rs:11:43 +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `OVERFLOW` + --> $DIR/offset_ub.rs:11:43 | LL | pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) }; - | ------------------------------------- inside `OVERFLOW` at $DIR/offset_ub.rs:11:43 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | overflowing in-bounds pointer arithmetic - | inside `ptr::const_ptr::<impl *const u16>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic | - ::: $DIR/offset_ub.rs:12:44 +note: inside `ptr::const_ptr::<impl *const u16>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `UNDERFLOW` + --> $DIR/offset_ub.rs:12:44 | LL | pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; - | ------------------------------------- inside `UNDERFLOW` at $DIR/offset_ub.rs:12:44 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | overflowing in-bounds pointer arithmetic - | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic | - ::: $DIR/offset_ub.rs:13:56 +note: inside `ptr::const_ptr::<impl *const u8>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `OVERFLOW_ADDRESS_SPACE` + --> $DIR/offset_ub.rs:13:56 | LL | pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) }; - | ----------------------------------- inside `OVERFLOW_ADDRESS_SPACE` at $DIR/offset_ub.rs:13:56 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | overflowing in-bounds pointer arithmetic - | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic + | +note: inside `ptr::const_ptr::<impl *const u8>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/offset_ub.rs:14:57 +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `UNDERFLOW_ADDRESS_SPACE` + --> $DIR/offset_ub.rs:14:57 | LL | pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; - | --------------------------- inside `UNDERFLOW_ADDRESS_SPACE` at $DIR/offset_ub.rs:14:57 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: allocN has size 1, so pointer to 2 bytes starting at offset -4 is out-of-bounds - | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: allocN has size 1, so pointer to 2 bytes starting at offset -4 is out-of-bounds | - ::: $DIR/offset_ub.rs:15:49 +note: inside `ptr::const_ptr::<impl *const u8>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `NEGATIVE_OFFSET` + --> $DIR/offset_ub.rs:15:49 | LL | pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; - | ------------------------------------------------ inside `NEGATIVE_OFFSET` at $DIR/offset_ub.rs:15:49 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: allocN has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds - | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: allocN has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds | - ::: $DIR/offset_ub.rs:17:50 +note: inside `ptr::const_ptr::<impl *const u8>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `ZERO_SIZED_ALLOC` + --> $DIR/offset_ub.rs:17:50 | LL | pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; - | --------------------------- inside `ZERO_SIZED_ALLOC` at $DIR/offset_ub.rs:17:50 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) as *mut T } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: 0x1[noalloc] is a dangling pointer (it has no provenance) - | inside `ptr::mut_ptr::<impl *mut u8>::offset` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: 0x1[noalloc] is a dangling pointer (it has no provenance) + | +note: inside `ptr::mut_ptr::<impl *mut u8>::offset` + --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL | - ::: $DIR/offset_ub.rs:18:42 +LL | unsafe { intrinsics::offset(self, count) as *mut T } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `DANGLING` + --> $DIR/offset_ub.rs:18:42 | LL | pub const DANGLING: *const u8 = unsafe { ptr::NonNull::<u8>::dangling().as_ptr().offset(4) }; - | ------------------------------------------------- inside `DANGLING` at $DIR/offset_ub.rs:18:42 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: null pointer is a dangling pointer (it has no provenance) - | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: null pointer is a dangling pointer (it has no provenance) | - ::: $DIR/offset_ub.rs:21:50 +note: inside `ptr::const_ptr::<impl *const u8>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `NULL_OFFSET_ZERO` + --> $DIR/offset_ub.rs:21:50 | LL | pub const NULL_OFFSET_ZERO: *const u8 = unsafe { ptr::null::<u8>().offset(0) }; - | --------------------------- inside `NULL_OFFSET_ZERO` at $DIR/offset_ub.rs:21:50 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: 0x7f..f[noalloc] is a dangling pointer (it has no provenance) - | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: 0x7f..f[noalloc] is a dangling pointer (it has no provenance) | - ::: $DIR/offset_ub.rs:24:47 +note: inside `ptr::const_ptr::<impl *const u8>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `UNDERFLOW_ABS` + --> $DIR/offset_ub.rs:24:47 | LL | pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) }; - | -------------------------------------------- inside `UNDERFLOW_ABS` at $DIR/offset_ub.rs:24:47 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 12 previous errors diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr index b71964b92c7..274753ef1bc 100644 --- a/src/test/ui/consts/ptr_comparisons.stderr +++ b/src/test/ui/consts/ptr_comparisons.stderr @@ -2,15 +2,18 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | LL | unsafe { intrinsics::offset(self, count) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | out-of-bounds pointer arithmetic: alloc3 has size $WORD, so pointer to $TWO_WORDS bytes starting at offset 0 is out-of-bounds - | inside `ptr::const_ptr::<impl *const usize>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: alloc3 has size $WORD, so pointer to $TWO_WORDS bytes starting at offset 0 is out-of-bounds + | +note: inside `ptr::const_ptr::<impl *const usize>::offset` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - ::: $DIR/ptr_comparisons.rs:50:34 +LL | unsafe { intrinsics::offset(self, count) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `_` + --> $DIR/ptr_comparisons.rs:50:34 | LL | const _: *const usize = unsafe { (FOO as *const usize).offset(2) }; - | ------------------------------- inside `_` at $DIR/ptr_comparisons.rs:50:34 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed --> $DIR/ptr_comparisons.rs:53:33 diff --git a/src/test/ui/consts/recursive.stderr b/src/test/ui/consts/recursive.stderr index 14fa3da7ab0..60ce64d2a1e 100644 --- a/src/test/ui/consts/recursive.stderr +++ b/src/test/ui/consts/recursive.stderr @@ -13,14 +13,23 @@ error[E0080]: evaluation of constant value failed --> $DIR/recursive.rs:4:5 | LL | f(x); + | ^^^^ reached the configured maximum number of stack frames + | +note: inside `f::<i32>` + --> $DIR/recursive.rs:4:5 + | +LL | f(x); | ^^^^ - | | - | reached the configured maximum number of stack frames - | inside `f::<i32>` at $DIR/recursive.rs:4:5 - | [... 126 additional calls inside `f::<i32>` at $DIR/recursive.rs:4:5 ...] -... +note: [... 126 additional calls inside `f::<i32>` ...] + --> $DIR/recursive.rs:4:5 + | +LL | f(x); + | ^^^^ +note: inside `X` + --> $DIR/recursive.rs:8:15 + | LL | const X: () = f(1); - | ---- inside `X` at $DIR/recursive.rs:8:15 + | ^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr index 8b39f390bb4..3a94e19313f 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr +++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr @@ -2,143 +2,648 @@ error[E0080]: evaluation of `<i32 as Const>::CONSTANT` failed --> $DIR/uninhabited-const-issue-61744.rs:4:5 | LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ reached the configured maximum number of stack frames + | +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() | ^^^^^^^^^^^^^^^^^^ - | | - | reached the configured maximum number of stack frames - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:4:5 -... -LL | fake_type() - | ----------- - | | - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 -... +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<!>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `hint_unreachable` + --> $DIR/uninhabited-const-issue-61744.rs:8:5 + | +LL | fake_type() + | ^^^^^^^^^^^ +note: inside `fake_type::<i32>` + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ +note: inside `<i32 as Const>::CONSTANT` + --> $DIR/uninhabited-const-issue-61744.rs:12:36 + | LL | const CONSTANT: i32 = unsafe { fake_type() }; - | ----------- inside `<i32 as Const>::CONSTANT` at $DIR/uninhabited-const-issue-61744.rs:12:36 + | ^^^^^^^^^^^ note: erroneous constant used --> $DIR/uninhabited-const-issue-61744.rs:18:10 diff --git a/src/test/ui/debuginfo/issue-105386-debuginfo-ub.rs b/src/test/ui/debuginfo/issue-105386-debuginfo-ub.rs new file mode 100644 index 00000000000..6c6eb5d4e86 --- /dev/null +++ b/src/test/ui/debuginfo/issue-105386-debuginfo-ub.rs @@ -0,0 +1,20 @@ +// run-pass +// compile-flags: --edition 2021 -Copt-level=3 -Cdebuginfo=2 -Zmir-opt-level=3 + +fn main() { + TranslatorI.visit_pre(); +} + +impl TranslatorI { + fn visit_pre(self) { + Some(()) + .map(|_| self.flags()) + .unwrap_or_else(|| self.flags()); + } +} + +struct TranslatorI; + +impl TranslatorI { + fn flags(&self) {} +} diff --git a/src/test/ui/diagnostic-width/long-E0308.rs b/src/test/ui/diagnostic-width/long-E0308.rs new file mode 100644 index 00000000000..3fd7a7110fd --- /dev/null +++ b/src/test/ui/diagnostic-width/long-E0308.rs @@ -0,0 +1,86 @@ +// compile-flags: --diagnostic-width=60 +// normalize-stderr-test: "long-type-\d+" -> "long-type-hash" + +struct Atype<T, K>(T, K); +struct Btype<T, K>(T, K); +struct Ctype<T, K>(T, K); + +fn main() { + let x: Atype< + Btype< + Ctype< + Atype< + Btype< + Ctype< + Atype< + Btype< + Ctype<i32, i32>, + i32 + >, + i32 + >, + i32 + >, + i32 + >, + i32 + >, + i32 + >, + i32 + >, + i32 + > = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok( + Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok( + Ok("") + )))))))))))))))))))))))))))))) + )))))))))))))))))))))))))))))); + //~^^^^^ ERROR E0308 + + let _ = Some(Ok(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( + Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( + Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( + Some(Some(Some(Some(Some(Some(Some(Some(Some(""))))))))) + ))))))))))))))))) + )))))))))))))))))) + ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok( + Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok( + Ok(Ok(Ok(Ok(Ok(Ok(Ok(""))))))) + )))))))))))))))))))))))))))))) + )))))))))))))))))))))))); + //~^^^^^ ERROR E0308 + + let x: Atype< + Btype< + Ctype< + Atype< + Btype< + Ctype< + Atype< + Btype< + Ctype<i32, i32>, + i32 + >, + i32 + >, + i32 + >, + i32 + >, + i32 + >, + i32 + >, + i32 + >, + i32 + > = (); + //~^ ERROR E0308 + + let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok( + Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok( + Ok(Ok(Ok(Ok(Ok(Ok(Ok(""))))))) + )))))))))))))))))))))))))))))) + )))))))))))))))))))))))); + //~^^^^^ ERROR E0308 +} diff --git a/src/test/ui/diagnostic-width/long-E0308.stderr b/src/test/ui/diagnostic-width/long-E0308.stderr new file mode 100644 index 00000000000..487ab23a1c1 --- /dev/null +++ b/src/test/ui/diagnostic-width/long-E0308.stderr @@ -0,0 +1,80 @@ +error[E0308]: mismatched types + --> $DIR/long-E0308.rs:33:9 + | +LL | let x: Atype< + | _____________- +LL | | Btype< +LL | | Ctype< +LL | | Atype< +... | +LL | | i32 +LL | | > = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok... + | | _____-___^ + | ||_____| + | | expected due to this +LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok... +LL | | Ok("") +LL | | )))))))))))))))))))))))))))))) +LL | | )))))))))))))))))))))))))))))); + | |__________________________________^ expected struct `Atype`, found enum `Result` + | + = note: expected struct `Atype<Btype<..., ...>, ...>` + the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' + found enum `Result<Result<..., ...>, ...>` + the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' + +error[E0308]: mismatched types + --> $DIR/long-E0308.rs:46:26 + | +LL | ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O... + | __________________________^ +LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(... +LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(""))))))) +LL | | )))))))))))))))))))))))))))))) +LL | | )))))))))))))))))))))))); + | |____________________________^ expected enum `Option`, found enum `Result` + | + = note: expected enum `Option<Result<..., ...>>` + the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' + found enum `Result<Result<..., ...>, ...>` + the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' + +error[E0308]: mismatched types + --> $DIR/long-E0308.rs:77:9 + | +LL | let x: Atype< + | ____________- +LL | | Btype< +LL | | Ctype< +LL | | Atype< +... | +LL | | i32 +LL | | > = (); + | | - ^^ expected struct `Atype`, found `()` + | |_____| + | expected due to this + | + = note: expected struct `Atype<Btype<..., ...>, ...>` + the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/long-E0308.rs:80:17 + | +LL | let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O... + | ____________--___^ + | | | + | | expected due to this +LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(... +LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(""))))))) +LL | | )))))))))))))))))))))))))))))) +LL | | )))))))))))))))))))))))); + | |____________________________^ expected `()`, found enum `Result` + | + = note: expected unit type `()` + found enum `Result<Result<..., ...>, ...>` + the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr index 49a4d984af9..451a683ac8a 100644 --- a/src/test/ui/error-codes/E0275.stderr +++ b/src/test/ui/error-codes/E0275.stderr @@ -5,7 +5,7 @@ LL | impl<T> Foo for T where Bar<T>: Foo {} | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`) -note: required for `Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>` to implement `Foo` +note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>>>>>>>>>>>>>>>>` to implement `Foo` --> $DIR/E0275.rs:6:9 | LL | impl<T> Foo for T where Bar<T>: Foo {} diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr index c485bc5c3ab..760dcb615c8 100644 --- a/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr +++ b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr @@ -3,12 +3,18 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t | LL | fn f() -> impl Fn() -> impl Sized { || () } | ^^^^^^^^^^ + | + = note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information + = help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32 | LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () } | ^^^^^^^^^^ + | + = note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information + = help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/inference/deref-suggestion.stderr b/src/test/ui/inference/deref-suggestion.stderr index 034005697b4..3db67cdb537 100644 --- a/src/test/ui/inference/deref-suggestion.stderr +++ b/src/test/ui/inference/deref-suggestion.stderr @@ -87,7 +87,10 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:37:5 | LL | assert_eq!(3i32, &3i32); - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `&i32` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected `i32`, found `&i32` + | expected because this is `i32` | = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/infinite/infinite-recursion-const-fn.stderr b/src/test/ui/infinite/infinite-recursion-const-fn.stderr index 620c9e110ff..53b603a47b5 100644 --- a/src/test/ui/infinite/infinite-recursion-const-fn.stderr +++ b/src/test/ui/infinite/infinite-recursion-const-fn.stderr @@ -2,143 +2,648 @@ error[E0080]: evaluation of constant value failed --> $DIR/infinite-recursion-const-fn.rs:4:5 | LL | b() + | ^^^ reached the configured maximum number of stack frames + | +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() | ^^^ - | | - | reached the configured maximum number of stack frames - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 - | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5 -... -LL | a() - | --- - | | - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 - | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5 -LL | } +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `b` + --> $DIR/infinite-recursion-const-fn.rs:7:5 + | +LL | a() + | ^^^ +note: inside `a` + --> $DIR/infinite-recursion-const-fn.rs:4:5 + | +LL | b() + | ^^^ +note: inside `ARR::{constant#0}` + --> $DIR/infinite-recursion-const-fn.rs:9:18 + | LL | const ARR: [i32; a()] = [5; 6]; - | --- inside `ARR::{constant#0}` at $DIR/infinite-recursion-const-fn.rs:9:18 + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/invalid/invalid-no-sanitize.stderr b/src/test/ui/invalid/invalid-no-sanitize.stderr index d328cafa00b..4600034952b 100644 --- a/src/test/ui/invalid/invalid-no-sanitize.stderr +++ b/src/test/ui/invalid/invalid-no-sanitize.stderr @@ -4,7 +4,7 @@ error: invalid argument for `no_sanitize` LL | #[no_sanitize(brontosaurus)] | ^^^^^^^^^^^^ | - = note: expected one of: `address`, `cfi`, `hwaddress`, `memory`, `memtag`, `shadow-call-stack`, or `thread` + = note: expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 91509ceace8..78df445972c 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -14,7 +14,7 @@ LL | impl<T> Foo for T where NoData<T>: Foo { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) -note: required for `NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>` to implement `Foo` +note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>>>>>>>` to implement `Foo` --> $DIR/issue-20413.rs:9:9 | LL | impl<T> Foo for T where NoData<T>: Foo { @@ -30,13 +30,13 @@ LL | impl<T> Bar for T where EvenLessData<T>: Baz { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) -note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar` +note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>` to implement `Bar` --> $DIR/issue-20413.rs:28:9 | LL | impl<T> Bar for T where EvenLessData<T>: Baz { | ^^^ ^ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt' -note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz` +note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>` to implement `Baz` --> $DIR/issue-20413.rs:35:9 | LL | impl<T> Baz for T where AlmostNoData<T>: Bar { @@ -52,13 +52,13 @@ LL | impl<T> Baz for T where AlmostNoData<T>: Bar { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) -note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz` +note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>` to implement `Baz` --> $DIR/issue-20413.rs:35:9 | LL | impl<T> Baz for T where AlmostNoData<T>: Bar { | ^^^ ^ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt' -note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar` +note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>` to implement `Bar` --> $DIR/issue-20413.rs:28:9 | LL | impl<T> Bar for T where EvenLessData<T>: Baz { diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr index 5828e027b59..1f50b06a0e4 100644 --- a/src/test/ui/issues/issue-23122-2.stderr +++ b/src/test/ui/issues/issue-23122-2.stderr @@ -5,7 +5,7 @@ LL | type Next = <GetNext<T::Next> as Next>::Next; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`) -note: required for `GetNext<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` +note: required for `GetNext<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` --> $DIR/issue-23122-2.rs:10:15 | LL | impl<T: Next> Next for GetNext<T> { diff --git a/src/test/ui/issues/issue-47486.stderr b/src/test/ui/issues/issue-47486.stderr index 2bd24f08c1e..c7e9af70e64 100644 --- a/src/test/ui/issues/issue-47486.stderr +++ b/src/test/ui/issues/issue-47486.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-47486.rs:2:10 | LL | () < std::mem::size_of::<_>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `usize` + | -- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `usize` + | | + | expected because this is `()` error[E0282]: type annotations needed --> $DIR/issue-47486.rs:3:11 diff --git a/src/test/ui/limits/issue-55878.stderr b/src/test/ui/limits/issue-55878.stderr index e35f9f14c7e..f17f8141b90 100644 --- a/src/test/ui/limits/issue-55878.stderr +++ b/src/test/ui/limits/issue-55878.stderr @@ -2,12 +2,18 @@ error[E0080]: values of the type `[u8; SIZE]` are too big for the current archit --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | intrinsics::size_of::<T>() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ inside `std::mem::size_of::<[u8; SIZE]>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - ::: $DIR/issue-55878.rs:7:26 +note: inside `std::mem::size_of::<[u8; SIZE]>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | +LL | intrinsics::size_of::<T>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `main` + --> $DIR/issue-55878.rs:7:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); - | ---------------------------------------------- inside `main` at $DIR/issue-55878.rs:7:26 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: erroneous constant used --> $DIR/issue-55878.rs:7:26 diff --git a/src/test/ui/lint/lint-missing-copy-implementations-allow.rs b/src/test/ui/lint/lint-missing-copy-implementations-allow.rs new file mode 100644 index 00000000000..051a905aed6 --- /dev/null +++ b/src/test/ui/lint/lint-missing-copy-implementations-allow.rs @@ -0,0 +1,35 @@ +// check-pass +#![deny(missing_copy_implementations)] + +// Don't recommend implementing Copy on something stateful like an iterator. +pub struct MyIterator { + num: u8, +} + +impl Iterator for MyIterator { + type Item = u8; + + fn next(&mut self) -> Option<Self::Item> { + todo!() + } +} + +pub struct Handle { + inner: *mut (), +} + +pub struct Handle2 { + inner: *const (), +} + +pub enum MaybeHandle { + Ptr(*mut ()), +} + +pub union UnionHandle { + ptr: *mut (), +} + +pub struct Array([u8; 2048]); + +fn main() {} diff --git a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed index 0b3fe9371f7..71ebaea8ed2 100644 --- a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed @@ -1,6 +1,6 @@ // run-rustfix -#![feature(box_patterns, stmt_expr_attributes)] +#![feature(box_patterns, stmt_expr_attributes, yeet_expr)] #![allow( dead_code, @@ -25,6 +25,13 @@ fn _no_lint_attr() { let _x = #[allow(dead_code)] (1 + 2); } +fn _no_lint_yeet() -> Result<(), ()> { + #[allow(unreachable_code)] + if (do yeet) {} + + Ok(()) +} + // Don't lint in these cases (#64106). fn or_patterns_no_lint() { match Box::new(0) { diff --git a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs index 1e78ec5f7d9..28b662dd024 100644 --- a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs @@ -1,6 +1,6 @@ // run-rustfix -#![feature(box_patterns, stmt_expr_attributes)] +#![feature(box_patterns, stmt_expr_attributes, yeet_expr)] #![allow( dead_code, @@ -25,6 +25,13 @@ fn _no_lint_attr() { let _x = #[allow(dead_code)] (1 + 2); } +fn _no_lint_yeet() -> Result<(), ()> { + #[allow(unreachable_code)] + if (do yeet) {} + + Ok(()) +} + // Don't lint in these cases (#64106). fn or_patterns_no_lint() { match Box::new(0) { diff --git a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr index c73884663c8..a5e69e6d938 100644 --- a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr @@ -76,7 +76,7 @@ LL + let _ = |a: u8| 0; | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:49:12 + --> $DIR/issue-54538-unused-parens-lint.rs:56:12 | LL | if let (0 | 1) = 0 {} | ^ ^ @@ -88,7 +88,7 @@ LL + if let 0 | 1 = 0 {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:50:13 + --> $DIR/issue-54538-unused-parens-lint.rs:57:13 | LL | if let ((0 | 1),) = (0,) {} | ^ ^ @@ -100,7 +100,7 @@ LL + if let (0 | 1,) = (0,) {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:51:13 + --> $DIR/issue-54538-unused-parens-lint.rs:58:13 | LL | if let [(0 | 1)] = [0] {} | ^ ^ @@ -112,7 +112,7 @@ LL + if let [0 | 1] = [0] {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:52:16 + --> $DIR/issue-54538-unused-parens-lint.rs:59:16 | LL | if let 0 | (1 | 2) = 0 {} | ^ ^ @@ -124,7 +124,7 @@ LL + if let 0 | 1 | 2 = 0 {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:54:15 + --> $DIR/issue-54538-unused-parens-lint.rs:61:15 | LL | if let TS((0 | 1)) = TS(0) {} | ^ ^ @@ -136,7 +136,7 @@ LL + if let TS(0 | 1) = TS(0) {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:56:20 + --> $DIR/issue-54538-unused-parens-lint.rs:63:20 | LL | if let NS { f: (0 | 1) } = (NS { f: 0 }) {} | ^ ^ @@ -148,7 +148,7 @@ LL + if let NS { f: 0 | 1 } = (NS { f: 0 }) {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:66:9 + --> $DIR/issue-54538-unused-parens-lint.rs:73:9 | LL | (_) => {} | ^ ^ @@ -160,7 +160,7 @@ LL + _ => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:67:9 + --> $DIR/issue-54538-unused-parens-lint.rs:74:9 | LL | (y) => {} | ^ ^ @@ -172,7 +172,7 @@ LL + y => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:68:9 + --> $DIR/issue-54538-unused-parens-lint.rs:75:9 | LL | (ref r) => {} | ^ ^ @@ -184,7 +184,7 @@ LL + ref r => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:69:9 + --> $DIR/issue-54538-unused-parens-lint.rs:76:9 | LL | (e @ 1...2) => {} | ^ ^ @@ -196,7 +196,7 @@ LL + e @ 1...2 => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:75:9 + --> $DIR/issue-54538-unused-parens-lint.rs:82:9 | LL | (e @ &(1...2)) => {} | ^ ^ @@ -208,7 +208,7 @@ LL + e @ &(1...2) => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:76:10 + --> $DIR/issue-54538-unused-parens-lint.rs:83:10 | LL | &(_) => {} | ^ ^ @@ -220,7 +220,7 @@ LL + &_ => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:87:9 + --> $DIR/issue-54538-unused-parens-lint.rs:94:9 | LL | (_) => {} | ^ ^ @@ -232,7 +232,7 @@ LL + _ => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:88:9 + --> $DIR/issue-54538-unused-parens-lint.rs:95:9 | LL | (y) => {} | ^ ^ @@ -244,7 +244,7 @@ LL + y => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:89:9 + --> $DIR/issue-54538-unused-parens-lint.rs:96:9 | LL | (ref r) => {} | ^ ^ @@ -256,7 +256,7 @@ LL + ref r => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:90:9 + --> $DIR/issue-54538-unused-parens-lint.rs:97:9 | LL | (e @ 1..=2) => {} | ^ ^ @@ -268,7 +268,7 @@ LL + e @ 1..=2 => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:96:9 + --> $DIR/issue-54538-unused-parens-lint.rs:103:9 | LL | (e @ &(1..=2)) => {} | ^ ^ @@ -280,7 +280,7 @@ LL + e @ &(1..=2) => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:97:10 + --> $DIR/issue-54538-unused-parens-lint.rs:104:10 | LL | &(_) => {} | ^ ^ diff --git a/src/test/ui/macros/macro-in-expression-context.stderr b/src/test/ui/macros/macro-in-expression-context.stderr index 1023189eaa3..36aba8aa08a 100644 --- a/src/test/ui/macros/macro-in-expression-context.stderr +++ b/src/test/ui/macros/macro-in-expression-context.stderr @@ -5,11 +5,13 @@ LL | assert_eq!("B", "B"); | ^^^^^^^^^ ... LL | foo!() - | ------- help: you might be missing a semicolon here: `;` - | | - | caused by the macro expansion here + | ------ caused by the macro expansion here | = note: the usage of `foo!` is likely invalid in expression context +help: you might be missing a semicolon here + | +LL | foo!(); + | + warning: trailing semicolon in macro used in expression position --> $DIR/macro-in-expression-context.rs:5:29 diff --git a/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs b/src/test/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs index cd6c5bf2719..cd6c5bf2719 100644 --- a/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs +++ b/src/test/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs diff --git a/src/test/ui/mir/validate/needs-reveal-all.rs b/src/test/ui/mir/validate/needs-reveal-all.rs new file mode 100644 index 00000000000..3852daf245e --- /dev/null +++ b/src/test/ui/mir/validate/needs-reveal-all.rs @@ -0,0 +1,52 @@ +// Regression test for #105009. the issue here was that even after the `RevealAll` pass, +// `validate` still used `Reveal::UserFacing`. This meant that it now ends up comparing +// opaque types with their revealed version, resulting in an ICE. +// +// We're using these flags to run the `RevealAll` pass while making it less likely to +// accidentally removing the assignment from `Foo<fn_ptr>` to `Foo<fn_def>`. + +// compile-flags: -Zinline_mir=yes -Zmir-opt-level=0 -Zvalidate-mir +// run-pass + +use std::hint::black_box; + +trait Func { + type Ret: Id; +} + +trait Id { + type Assoc; +} +impl Id for u32 { + type Assoc = u32; +} +impl Id for i32 { + type Assoc = i32; +} + +impl<F: FnOnce() -> R, R: Id> Func for F { + type Ret = R; +} + +fn bar() -> impl Copy + Id { + 0u32 +} + +struct Foo<T: Func> { + _func: T, + value: Option<<<T as Func>::Ret as Id>::Assoc>, +} + +fn main() { + let mut fn_def = black_box(Foo { + _func: bar, + value: None, + }); + let fn_ptr = black_box(Foo { + _func: bar as fn() -> _, + value: None, + }); + + fn_def.value = fn_ptr.value; + black_box(fn_def); +} diff --git a/src/test/ui/numeric/numeric-cast-binop.stderr b/src/test/ui/numeric/numeric-cast-binop.stderr index 2f58f164985..d5213e3f5b6 100644 --- a/src/test/ui/numeric/numeric-cast-binop.stderr +++ b/src/test/ui/numeric/numeric-cast-binop.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:23:16 | LL | x_u8 > x_u16; - | ^^^^^ expected `u8`, found `u16` + | ---- ^^^^^ expected `u8`, found `u16` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `u16`, matching the type of `x_u16` | @@ -13,7 +15,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:25:16 | LL | x_u8 > x_u32; - | ^^^^^ expected `u8`, found `u32` + | ---- ^^^^^ expected `u8`, found `u32` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `u32`, matching the type of `x_u32` | @@ -24,7 +28,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:27:16 | LL | x_u8 > x_u64; - | ^^^^^ expected `u8`, found `u64` + | ---- ^^^^^ expected `u8`, found `u64` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `u64`, matching the type of `x_u64` | @@ -35,7 +41,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:29:16 | LL | x_u8 > x_u128; - | ^^^^^^ expected `u8`, found `u128` + | ---- ^^^^^^ expected `u8`, found `u128` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `u128`, matching the type of `x_u128` | @@ -46,7 +54,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:31:16 | LL | x_u8 > x_usize; - | ^^^^^^^ expected `u8`, found `usize` + | ---- ^^^^^^^ expected `u8`, found `usize` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `usize`, matching the type of `x_usize` | @@ -57,7 +67,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:34:17 | LL | x_u16 > x_u8; - | ^^^^ expected `u16`, found `u8` + | ----- ^^^^ expected `u16`, found `u8` + | | + | expected because this is `u16` | help: you can convert a `u8` to a `u16` | @@ -68,7 +80,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:36:17 | LL | x_u16 > x_u32; - | ^^^^^ expected `u16`, found `u32` + | ----- ^^^^^ expected `u16`, found `u32` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `u32`, matching the type of `x_u32` | @@ -79,7 +93,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:38:17 | LL | x_u16 > x_u64; - | ^^^^^ expected `u16`, found `u64` + | ----- ^^^^^ expected `u16`, found `u64` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `u64`, matching the type of `x_u64` | @@ -90,7 +106,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:40:17 | LL | x_u16 > x_u128; - | ^^^^^^ expected `u16`, found `u128` + | ----- ^^^^^^ expected `u16`, found `u128` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `u128`, matching the type of `x_u128` | @@ -101,7 +119,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:42:17 | LL | x_u16 > x_usize; - | ^^^^^^^ expected `u16`, found `usize` + | ----- ^^^^^^^ expected `u16`, found `usize` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `usize`, matching the type of `x_usize` | @@ -112,7 +132,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:45:17 | LL | x_u32 > x_u8; - | ^^^^ expected `u32`, found `u8` + | ----- ^^^^ expected `u32`, found `u8` + | | + | expected because this is `u32` | help: you can convert a `u8` to a `u32` | @@ -123,7 +145,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:47:17 | LL | x_u32 > x_u16; - | ^^^^^ expected `u32`, found `u16` + | ----- ^^^^^ expected `u32`, found `u16` + | | + | expected because this is `u32` | help: you can convert a `u16` to a `u32` | @@ -134,7 +158,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:49:17 | LL | x_u32 > x_u64; - | ^^^^^ expected `u32`, found `u64` + | ----- ^^^^^ expected `u32`, found `u64` + | | + | expected because this is `u32` | help: you can convert `x_u32` from `u32` to `u64`, matching the type of `x_u64` | @@ -145,7 +171,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:51:17 | LL | x_u32 > x_u128; - | ^^^^^^ expected `u32`, found `u128` + | ----- ^^^^^^ expected `u32`, found `u128` + | | + | expected because this is `u32` | help: you can convert `x_u32` from `u32` to `u128`, matching the type of `x_u128` | @@ -156,7 +184,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:53:17 | LL | x_u32 > x_usize; - | ^^^^^^^ expected `u32`, found `usize` + | ----- ^^^^^^^ expected `u32`, found `usize` + | | + | expected because this is `u32` | help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit | @@ -167,7 +197,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:56:17 | LL | x_u64 > x_u8; - | ^^^^ expected `u64`, found `u8` + | ----- ^^^^ expected `u64`, found `u8` + | | + | expected because this is `u64` | help: you can convert a `u8` to a `u64` | @@ -178,7 +210,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:58:17 | LL | x_u64 > x_u16; - | ^^^^^ expected `u64`, found `u16` + | ----- ^^^^^ expected `u64`, found `u16` + | | + | expected because this is `u64` | help: you can convert a `u16` to a `u64` | @@ -189,7 +223,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:60:17 | LL | x_u64 > x_u32; - | ^^^^^ expected `u64`, found `u32` + | ----- ^^^^^ expected `u64`, found `u32` + | | + | expected because this is `u64` | help: you can convert a `u32` to a `u64` | @@ -200,7 +236,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:62:17 | LL | x_u64 > x_u128; - | ^^^^^^ expected `u64`, found `u128` + | ----- ^^^^^^ expected `u64`, found `u128` + | | + | expected because this is `u64` | help: you can convert `x_u64` from `u64` to `u128`, matching the type of `x_u128` | @@ -211,7 +249,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:64:17 | LL | x_u64 > x_usize; - | ^^^^^^^ expected `u64`, found `usize` + | ----- ^^^^^^^ expected `u64`, found `usize` + | | + | expected because this is `u64` | help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit | @@ -222,7 +262,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:67:18 | LL | x_u128 > x_u8; - | ^^^^ expected `u128`, found `u8` + | ------ ^^^^ expected `u128`, found `u8` + | | + | expected because this is `u128` | help: you can convert a `u8` to a `u128` | @@ -233,7 +275,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:69:18 | LL | x_u128 > x_u16; - | ^^^^^ expected `u128`, found `u16` + | ------ ^^^^^ expected `u128`, found `u16` + | | + | expected because this is `u128` | help: you can convert a `u16` to a `u128` | @@ -244,7 +288,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:71:18 | LL | x_u128 > x_u32; - | ^^^^^ expected `u128`, found `u32` + | ------ ^^^^^ expected `u128`, found `u32` + | | + | expected because this is `u128` | help: you can convert a `u32` to a `u128` | @@ -255,7 +301,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:73:18 | LL | x_u128 > x_u64; - | ^^^^^ expected `u128`, found `u64` + | ------ ^^^^^ expected `u128`, found `u64` + | | + | expected because this is `u128` | help: you can convert a `u64` to a `u128` | @@ -266,7 +314,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:75:18 | LL | x_u128 > x_usize; - | ^^^^^^^ expected `u128`, found `usize` + | ------ ^^^^^^^ expected `u128`, found `usize` + | | + | expected because this is `u128` | help: you can convert a `usize` to a `u128` and panic if the converted value doesn't fit | @@ -277,7 +327,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:78:19 | LL | x_usize > x_u8; - | ^^^^ expected `usize`, found `u8` + | ------- ^^^^ expected `usize`, found `u8` + | | + | expected because this is `usize` | help: you can convert a `u8` to a `usize` | @@ -288,7 +340,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:80:19 | LL | x_usize > x_u16; - | ^^^^^ expected `usize`, found `u16` + | ------- ^^^^^ expected `usize`, found `u16` + | | + | expected because this is `usize` | help: you can convert a `u16` to a `usize` | @@ -299,7 +353,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:82:19 | LL | x_usize > x_u32; - | ^^^^^ expected `usize`, found `u32` + | ------- ^^^^^ expected `usize`, found `u32` + | | + | expected because this is `usize` | help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit | @@ -310,7 +366,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:84:19 | LL | x_usize > x_u64; - | ^^^^^ expected `usize`, found `u64` + | ------- ^^^^^ expected `usize`, found `u64` + | | + | expected because this is `usize` | help: you can convert a `u64` to a `usize` and panic if the converted value doesn't fit | @@ -321,7 +379,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:86:19 | LL | x_usize > x_u128; - | ^^^^^^ expected `usize`, found `u128` + | ------- ^^^^^^ expected `usize`, found `u128` + | | + | expected because this is `usize` | help: you can convert a `u128` to a `usize` and panic if the converted value doesn't fit | @@ -332,7 +392,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:92:16 | LL | x_i8 > x_i16; - | ^^^^^ expected `i8`, found `i16` + | ---- ^^^^^ expected `i8`, found `i16` + | | + | expected because this is `i8` | help: you can convert `x_i8` from `i8` to `i16`, matching the type of `x_i16` | @@ -343,7 +405,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:94:16 | LL | x_i8 > x_i32; - | ^^^^^ expected `i8`, found `i32` + | ---- ^^^^^ expected `i8`, found `i32` + | | + | expected because this is `i8` | help: you can convert `x_i8` from `i8` to `i32`, matching the type of `x_i32` | @@ -354,7 +418,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:96:16 | LL | x_i8 > x_i64; - | ^^^^^ expected `i8`, found `i64` + | ---- ^^^^^ expected `i8`, found `i64` + | | + | expected because this is `i8` | help: you can convert `x_i8` from `i8` to `i64`, matching the type of `x_i64` | @@ -365,7 +431,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:98:16 | LL | x_i8 > x_i128; - | ^^^^^^ expected `i8`, found `i128` + | ---- ^^^^^^ expected `i8`, found `i128` + | | + | expected because this is `i8` | help: you can convert `x_i8` from `i8` to `i128`, matching the type of `x_i128` | @@ -376,7 +444,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:100:16 | LL | x_i8 > x_isize; - | ^^^^^^^ expected `i8`, found `isize` + | ---- ^^^^^^^ expected `i8`, found `isize` + | | + | expected because this is `i8` | help: you can convert `x_i8` from `i8` to `isize`, matching the type of `x_isize` | @@ -387,7 +457,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:103:17 | LL | x_i16 > x_i8; - | ^^^^ expected `i16`, found `i8` + | ----- ^^^^ expected `i16`, found `i8` + | | + | expected because this is `i16` | help: you can convert an `i8` to an `i16` | @@ -398,7 +470,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:105:17 | LL | x_i16 > x_i32; - | ^^^^^ expected `i16`, found `i32` + | ----- ^^^^^ expected `i16`, found `i32` + | | + | expected because this is `i16` | help: you can convert `x_i16` from `i16` to `i32`, matching the type of `x_i32` | @@ -409,7 +483,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:107:17 | LL | x_i16 > x_i64; - | ^^^^^ expected `i16`, found `i64` + | ----- ^^^^^ expected `i16`, found `i64` + | | + | expected because this is `i16` | help: you can convert `x_i16` from `i16` to `i64`, matching the type of `x_i64` | @@ -420,7 +496,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:109:17 | LL | x_i16 > x_i128; - | ^^^^^^ expected `i16`, found `i128` + | ----- ^^^^^^ expected `i16`, found `i128` + | | + | expected because this is `i16` | help: you can convert `x_i16` from `i16` to `i128`, matching the type of `x_i128` | @@ -431,7 +509,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:111:17 | LL | x_i16 > x_isize; - | ^^^^^^^ expected `i16`, found `isize` + | ----- ^^^^^^^ expected `i16`, found `isize` + | | + | expected because this is `i16` | help: you can convert `x_i16` from `i16` to `isize`, matching the type of `x_isize` | @@ -442,7 +522,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:114:17 | LL | x_i32 > x_i8; - | ^^^^ expected `i32`, found `i8` + | ----- ^^^^ expected `i32`, found `i8` + | | + | expected because this is `i32` | help: you can convert an `i8` to an `i32` | @@ -453,7 +535,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:116:17 | LL | x_i32 > x_i16; - | ^^^^^ expected `i32`, found `i16` + | ----- ^^^^^ expected `i32`, found `i16` + | | + | expected because this is `i32` | help: you can convert an `i16` to an `i32` | @@ -464,7 +548,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:118:17 | LL | x_i32 > x_i64; - | ^^^^^ expected `i32`, found `i64` + | ----- ^^^^^ expected `i32`, found `i64` + | | + | expected because this is `i32` | help: you can convert `x_i32` from `i32` to `i64`, matching the type of `x_i64` | @@ -475,7 +561,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:120:17 | LL | x_i32 > x_i128; - | ^^^^^^ expected `i32`, found `i128` + | ----- ^^^^^^ expected `i32`, found `i128` + | | + | expected because this is `i32` | help: you can convert `x_i32` from `i32` to `i128`, matching the type of `x_i128` | @@ -486,7 +574,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:122:17 | LL | x_i32 > x_isize; - | ^^^^^^^ expected `i32`, found `isize` + | ----- ^^^^^^^ expected `i32`, found `isize` + | | + | expected because this is `i32` | help: you can convert an `isize` to an `i32` and panic if the converted value doesn't fit | @@ -497,7 +587,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:125:17 | LL | x_i64 > x_i8; - | ^^^^ expected `i64`, found `i8` + | ----- ^^^^ expected `i64`, found `i8` + | | + | expected because this is `i64` | help: you can convert an `i8` to an `i64` | @@ -508,7 +600,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:127:17 | LL | x_i64 > x_i16; - | ^^^^^ expected `i64`, found `i16` + | ----- ^^^^^ expected `i64`, found `i16` + | | + | expected because this is `i64` | help: you can convert an `i16` to an `i64` | @@ -519,7 +613,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:129:17 | LL | x_i64 > x_i32; - | ^^^^^ expected `i64`, found `i32` + | ----- ^^^^^ expected `i64`, found `i32` + | | + | expected because this is `i64` | help: you can convert an `i32` to an `i64` | @@ -530,7 +626,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:131:17 | LL | x_i64 > x_i128; - | ^^^^^^ expected `i64`, found `i128` + | ----- ^^^^^^ expected `i64`, found `i128` + | | + | expected because this is `i64` | help: you can convert `x_i64` from `i64` to `i128`, matching the type of `x_i128` | @@ -541,7 +639,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:133:17 | LL | x_i64 > x_isize; - | ^^^^^^^ expected `i64`, found `isize` + | ----- ^^^^^^^ expected `i64`, found `isize` + | | + | expected because this is `i64` | help: you can convert an `isize` to an `i64` and panic if the converted value doesn't fit | @@ -552,7 +652,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:136:18 | LL | x_i128 > x_i8; - | ^^^^ expected `i128`, found `i8` + | ------ ^^^^ expected `i128`, found `i8` + | | + | expected because this is `i128` | help: you can convert an `i8` to an `i128` | @@ -563,7 +665,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:138:18 | LL | x_i128 > x_i16; - | ^^^^^ expected `i128`, found `i16` + | ------ ^^^^^ expected `i128`, found `i16` + | | + | expected because this is `i128` | help: you can convert an `i16` to an `i128` | @@ -574,7 +678,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:140:18 | LL | x_i128 > x_i32; - | ^^^^^ expected `i128`, found `i32` + | ------ ^^^^^ expected `i128`, found `i32` + | | + | expected because this is `i128` | help: you can convert an `i32` to an `i128` | @@ -585,7 +691,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:142:18 | LL | x_i128 > x_i64; - | ^^^^^ expected `i128`, found `i64` + | ------ ^^^^^ expected `i128`, found `i64` + | | + | expected because this is `i128` | help: you can convert an `i64` to an `i128` | @@ -596,7 +704,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:144:18 | LL | x_i128 > x_isize; - | ^^^^^^^ expected `i128`, found `isize` + | ------ ^^^^^^^ expected `i128`, found `isize` + | | + | expected because this is `i128` | help: you can convert an `isize` to an `i128` and panic if the converted value doesn't fit | @@ -607,7 +717,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:147:19 | LL | x_isize > x_i8; - | ^^^^ expected `isize`, found `i8` + | ------- ^^^^ expected `isize`, found `i8` + | | + | expected because this is `isize` | help: you can convert an `i8` to an `isize` | @@ -618,7 +730,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:149:19 | LL | x_isize > x_i16; - | ^^^^^ expected `isize`, found `i16` + | ------- ^^^^^ expected `isize`, found `i16` + | | + | expected because this is `isize` | help: you can convert an `i16` to an `isize` | @@ -629,7 +743,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:151:19 | LL | x_isize > x_i32; - | ^^^^^ expected `isize`, found `i32` + | ------- ^^^^^ expected `isize`, found `i32` + | | + | expected because this is `isize` | help: you can convert an `i32` to an `isize` and panic if the converted value doesn't fit | @@ -640,7 +756,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:153:19 | LL | x_isize > x_i64; - | ^^^^^ expected `isize`, found `i64` + | ------- ^^^^^ expected `isize`, found `i64` + | | + | expected because this is `isize` | help: you can convert an `i64` to an `isize` and panic if the converted value doesn't fit | @@ -651,7 +769,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:155:19 | LL | x_isize > x_i128; - | ^^^^^^ expected `isize`, found `i128` + | ------- ^^^^^^ expected `isize`, found `i128` + | | + | expected because this is `isize` | help: you can convert an `i128` to an `isize` and panic if the converted value doesn't fit | @@ -662,7 +782,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:161:16 | LL | x_u8 > x_i8; - | ^^^^ expected `u8`, found `i8` + | ---- ^^^^ expected `u8`, found `i8` + | | + | expected because this is `u8` | help: you can convert an `i8` to a `u8` and panic if the converted value doesn't fit | @@ -673,7 +795,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:163:16 | LL | x_u8 > x_i16; - | ^^^^^ expected `u8`, found `i16` + | ---- ^^^^^ expected `u8`, found `i16` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `i16`, matching the type of `x_i16` | @@ -684,7 +808,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:165:16 | LL | x_u8 > x_i32; - | ^^^^^ expected `u8`, found `i32` + | ---- ^^^^^ expected `u8`, found `i32` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `i32`, matching the type of `x_i32` | @@ -695,7 +821,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:167:16 | LL | x_u8 > x_i64; - | ^^^^^ expected `u8`, found `i64` + | ---- ^^^^^ expected `u8`, found `i64` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `i64`, matching the type of `x_i64` | @@ -706,7 +834,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:169:16 | LL | x_u8 > x_i128; - | ^^^^^^ expected `u8`, found `i128` + | ---- ^^^^^^ expected `u8`, found `i128` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `i128`, matching the type of `x_i128` | @@ -717,7 +847,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:171:16 | LL | x_u8 > x_isize; - | ^^^^^^^ expected `u8`, found `isize` + | ---- ^^^^^^^ expected `u8`, found `isize` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `isize`, matching the type of `x_isize` | @@ -728,7 +860,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:174:17 | LL | x_u16 > x_i8; - | ^^^^ expected `u16`, found `i8` + | ----- ^^^^ expected `u16`, found `i8` + | | + | expected because this is `u16` | help: you can convert an `i8` to a `u16` and panic if the converted value doesn't fit | @@ -739,7 +873,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:176:17 | LL | x_u16 > x_i16; - | ^^^^^ expected `u16`, found `i16` + | ----- ^^^^^ expected `u16`, found `i16` + | | + | expected because this is `u16` | help: you can convert an `i16` to a `u16` and panic if the converted value doesn't fit | @@ -750,7 +886,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:178:17 | LL | x_u16 > x_i32; - | ^^^^^ expected `u16`, found `i32` + | ----- ^^^^^ expected `u16`, found `i32` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `i32`, matching the type of `x_i32` | @@ -761,7 +899,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:180:17 | LL | x_u16 > x_i64; - | ^^^^^ expected `u16`, found `i64` + | ----- ^^^^^ expected `u16`, found `i64` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `i64`, matching the type of `x_i64` | @@ -772,7 +912,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:182:17 | LL | x_u16 > x_i128; - | ^^^^^^ expected `u16`, found `i128` + | ----- ^^^^^^ expected `u16`, found `i128` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `i128`, matching the type of `x_i128` | @@ -783,7 +925,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:184:17 | LL | x_u16 > x_isize; - | ^^^^^^^ expected `u16`, found `isize` + | ----- ^^^^^^^ expected `u16`, found `isize` + | | + | expected because this is `u16` | help: you can convert an `isize` to a `u16` and panic if the converted value doesn't fit | @@ -794,7 +938,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:187:17 | LL | x_u32 > x_i8; - | ^^^^ expected `u32`, found `i8` + | ----- ^^^^ expected `u32`, found `i8` + | | + | expected because this is `u32` | help: you can convert an `i8` to a `u32` and panic if the converted value doesn't fit | @@ -805,7 +951,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:189:17 | LL | x_u32 > x_i16; - | ^^^^^ expected `u32`, found `i16` + | ----- ^^^^^ expected `u32`, found `i16` + | | + | expected because this is `u32` | help: you can convert an `i16` to a `u32` and panic if the converted value doesn't fit | @@ -816,7 +964,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:191:17 | LL | x_u32 > x_i32; - | ^^^^^ expected `u32`, found `i32` + | ----- ^^^^^ expected `u32`, found `i32` + | | + | expected because this is `u32` | help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit | @@ -827,7 +977,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:193:17 | LL | x_u32 > x_i64; - | ^^^^^ expected `u32`, found `i64` + | ----- ^^^^^ expected `u32`, found `i64` + | | + | expected because this is `u32` | help: you can convert `x_u32` from `u32` to `i64`, matching the type of `x_i64` | @@ -838,7 +990,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:195:17 | LL | x_u32 > x_i128; - | ^^^^^^ expected `u32`, found `i128` + | ----- ^^^^^^ expected `u32`, found `i128` + | | + | expected because this is `u32` | help: you can convert `x_u32` from `u32` to `i128`, matching the type of `x_i128` | @@ -849,7 +1003,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:197:17 | LL | x_u32 > x_isize; - | ^^^^^^^ expected `u32`, found `isize` + | ----- ^^^^^^^ expected `u32`, found `isize` + | | + | expected because this is `u32` | help: you can convert an `isize` to a `u32` and panic if the converted value doesn't fit | @@ -860,7 +1016,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:200:17 | LL | x_u64 > x_i8; - | ^^^^ expected `u64`, found `i8` + | ----- ^^^^ expected `u64`, found `i8` + | | + | expected because this is `u64` | help: you can convert an `i8` to a `u64` and panic if the converted value doesn't fit | @@ -871,7 +1029,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:202:17 | LL | x_u64 > x_i16; - | ^^^^^ expected `u64`, found `i16` + | ----- ^^^^^ expected `u64`, found `i16` + | | + | expected because this is `u64` | help: you can convert an `i16` to a `u64` and panic if the converted value doesn't fit | @@ -882,7 +1042,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:204:17 | LL | x_u64 > x_i32; - | ^^^^^ expected `u64`, found `i32` + | ----- ^^^^^ expected `u64`, found `i32` + | | + | expected because this is `u64` | help: you can convert an `i32` to a `u64` and panic if the converted value doesn't fit | @@ -893,7 +1055,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:206:17 | LL | x_u64 > x_i64; - | ^^^^^ expected `u64`, found `i64` + | ----- ^^^^^ expected `u64`, found `i64` + | | + | expected because this is `u64` | help: you can convert an `i64` to a `u64` and panic if the converted value doesn't fit | @@ -904,7 +1068,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:208:17 | LL | x_u64 > x_i128; - | ^^^^^^ expected `u64`, found `i128` + | ----- ^^^^^^ expected `u64`, found `i128` + | | + | expected because this is `u64` | help: you can convert `x_u64` from `u64` to `i128`, matching the type of `x_i128` | @@ -915,7 +1081,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:210:17 | LL | x_u64 > x_isize; - | ^^^^^^^ expected `u64`, found `isize` + | ----- ^^^^^^^ expected `u64`, found `isize` + | | + | expected because this is `u64` | help: you can convert an `isize` to a `u64` and panic if the converted value doesn't fit | @@ -926,7 +1094,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:213:18 | LL | x_u128 > x_i8; - | ^^^^ expected `u128`, found `i8` + | ------ ^^^^ expected `u128`, found `i8` + | | + | expected because this is `u128` | help: you can convert an `i8` to a `u128` and panic if the converted value doesn't fit | @@ -937,7 +1107,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:215:18 | LL | x_u128 > x_i16; - | ^^^^^ expected `u128`, found `i16` + | ------ ^^^^^ expected `u128`, found `i16` + | | + | expected because this is `u128` | help: you can convert an `i16` to a `u128` and panic if the converted value doesn't fit | @@ -948,7 +1120,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:217:18 | LL | x_u128 > x_i32; - | ^^^^^ expected `u128`, found `i32` + | ------ ^^^^^ expected `u128`, found `i32` + | | + | expected because this is `u128` | help: you can convert an `i32` to a `u128` and panic if the converted value doesn't fit | @@ -959,7 +1133,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:219:18 | LL | x_u128 > x_i64; - | ^^^^^ expected `u128`, found `i64` + | ------ ^^^^^ expected `u128`, found `i64` + | | + | expected because this is `u128` | help: you can convert an `i64` to a `u128` and panic if the converted value doesn't fit | @@ -970,7 +1146,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:221:18 | LL | x_u128 > x_i128; - | ^^^^^^ expected `u128`, found `i128` + | ------ ^^^^^^ expected `u128`, found `i128` + | | + | expected because this is `u128` | help: you can convert an `i128` to a `u128` and panic if the converted value doesn't fit | @@ -981,7 +1159,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:223:18 | LL | x_u128 > x_isize; - | ^^^^^^^ expected `u128`, found `isize` + | ------ ^^^^^^^ expected `u128`, found `isize` + | | + | expected because this is `u128` | help: you can convert an `isize` to a `u128` and panic if the converted value doesn't fit | @@ -992,7 +1172,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:226:19 | LL | x_usize > x_i8; - | ^^^^ expected `usize`, found `i8` + | ------- ^^^^ expected `usize`, found `i8` + | | + | expected because this is `usize` | help: you can convert an `i8` to a `usize` and panic if the converted value doesn't fit | @@ -1003,7 +1185,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:228:19 | LL | x_usize > x_i16; - | ^^^^^ expected `usize`, found `i16` + | ------- ^^^^^ expected `usize`, found `i16` + | | + | expected because this is `usize` | help: you can convert an `i16` to a `usize` and panic if the converted value doesn't fit | @@ -1014,7 +1198,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:230:19 | LL | x_usize > x_i32; - | ^^^^^ expected `usize`, found `i32` + | ------- ^^^^^ expected `usize`, found `i32` + | | + | expected because this is `usize` | help: you can convert an `i32` to a `usize` and panic if the converted value doesn't fit | @@ -1025,7 +1211,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:232:19 | LL | x_usize > x_i64; - | ^^^^^ expected `usize`, found `i64` + | ------- ^^^^^ expected `usize`, found `i64` + | | + | expected because this is `usize` | help: you can convert an `i64` to a `usize` and panic if the converted value doesn't fit | @@ -1036,7 +1224,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:234:19 | LL | x_usize > x_i128; - | ^^^^^^ expected `usize`, found `i128` + | ------- ^^^^^^ expected `usize`, found `i128` + | | + | expected because this is `usize` | help: you can convert an `i128` to a `usize` and panic if the converted value doesn't fit | @@ -1047,7 +1237,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:236:19 | LL | x_usize > x_isize; - | ^^^^^^^ expected `usize`, found `isize` + | ------- ^^^^^^^ expected `usize`, found `isize` + | | + | expected because this is `usize` | help: you can convert an `isize` to a `usize` and panic if the converted value doesn't fit | @@ -1058,7 +1250,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:242:16 | LL | x_i8 > x_u8; - | ^^^^ expected `i8`, found `u8` + | ---- ^^^^ expected `i8`, found `u8` + | | + | expected because this is `i8` | help: you can convert a `u8` to an `i8` and panic if the converted value doesn't fit | @@ -1069,7 +1263,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:244:16 | LL | x_i8 > x_u16; - | ^^^^^ expected `i8`, found `u16` + | ---- ^^^^^ expected `i8`, found `u16` + | | + | expected because this is `i8` | help: you can convert a `u16` to an `i8` and panic if the converted value doesn't fit | @@ -1080,7 +1276,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:246:16 | LL | x_i8 > x_u32; - | ^^^^^ expected `i8`, found `u32` + | ---- ^^^^^ expected `i8`, found `u32` + | | + | expected because this is `i8` | help: you can convert a `u32` to an `i8` and panic if the converted value doesn't fit | @@ -1091,7 +1289,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:248:16 | LL | x_i8 > x_u64; - | ^^^^^ expected `i8`, found `u64` + | ---- ^^^^^ expected `i8`, found `u64` + | | + | expected because this is `i8` | help: you can convert a `u64` to an `i8` and panic if the converted value doesn't fit | @@ -1102,7 +1302,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:250:16 | LL | x_i8 > x_u128; - | ^^^^^^ expected `i8`, found `u128` + | ---- ^^^^^^ expected `i8`, found `u128` + | | + | expected because this is `i8` | help: you can convert a `u128` to an `i8` and panic if the converted value doesn't fit | @@ -1113,7 +1315,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:252:16 | LL | x_i8 > x_usize; - | ^^^^^^^ expected `i8`, found `usize` + | ---- ^^^^^^^ expected `i8`, found `usize` + | | + | expected because this is `i8` | help: you can convert a `usize` to an `i8` and panic if the converted value doesn't fit | @@ -1124,7 +1328,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:255:17 | LL | x_i16 > x_u8; - | ^^^^ expected `i16`, found `u8` + | ----- ^^^^ expected `i16`, found `u8` + | | + | expected because this is `i16` | help: you can convert a `u8` to an `i16` | @@ -1135,7 +1341,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:257:17 | LL | x_i16 > x_u16; - | ^^^^^ expected `i16`, found `u16` + | ----- ^^^^^ expected `i16`, found `u16` + | | + | expected because this is `i16` | help: you can convert a `u16` to an `i16` and panic if the converted value doesn't fit | @@ -1146,7 +1354,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:259:17 | LL | x_i16 > x_u32; - | ^^^^^ expected `i16`, found `u32` + | ----- ^^^^^ expected `i16`, found `u32` + | | + | expected because this is `i16` | help: you can convert a `u32` to an `i16` and panic if the converted value doesn't fit | @@ -1157,7 +1367,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:261:17 | LL | x_i16 > x_u64; - | ^^^^^ expected `i16`, found `u64` + | ----- ^^^^^ expected `i16`, found `u64` + | | + | expected because this is `i16` | help: you can convert a `u64` to an `i16` and panic if the converted value doesn't fit | @@ -1168,7 +1380,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:263:17 | LL | x_i16 > x_u128; - | ^^^^^^ expected `i16`, found `u128` + | ----- ^^^^^^ expected `i16`, found `u128` + | | + | expected because this is `i16` | help: you can convert a `u128` to an `i16` and panic if the converted value doesn't fit | @@ -1179,7 +1393,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:265:17 | LL | x_i16 > x_usize; - | ^^^^^^^ expected `i16`, found `usize` + | ----- ^^^^^^^ expected `i16`, found `usize` + | | + | expected because this is `i16` | help: you can convert a `usize` to an `i16` and panic if the converted value doesn't fit | @@ -1190,7 +1406,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:268:17 | LL | x_i32 > x_u8; - | ^^^^ expected `i32`, found `u8` + | ----- ^^^^ expected `i32`, found `u8` + | | + | expected because this is `i32` | help: you can convert a `u8` to an `i32` | @@ -1201,7 +1419,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:270:17 | LL | x_i32 > x_u16; - | ^^^^^ expected `i32`, found `u16` + | ----- ^^^^^ expected `i32`, found `u16` + | | + | expected because this is `i32` | help: you can convert a `u16` to an `i32` | @@ -1212,7 +1432,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:272:17 | LL | x_i32 > x_u32; - | ^^^^^ expected `i32`, found `u32` + | ----- ^^^^^ expected `i32`, found `u32` + | | + | expected because this is `i32` | help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit | @@ -1223,7 +1445,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:274:17 | LL | x_i32 > x_u64; - | ^^^^^ expected `i32`, found `u64` + | ----- ^^^^^ expected `i32`, found `u64` + | | + | expected because this is `i32` | help: you can convert a `u64` to an `i32` and panic if the converted value doesn't fit | @@ -1234,7 +1458,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:276:17 | LL | x_i32 > x_u128; - | ^^^^^^ expected `i32`, found `u128` + | ----- ^^^^^^ expected `i32`, found `u128` + | | + | expected because this is `i32` | help: you can convert a `u128` to an `i32` and panic if the converted value doesn't fit | @@ -1245,7 +1471,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:278:17 | LL | x_i32 > x_usize; - | ^^^^^^^ expected `i32`, found `usize` + | ----- ^^^^^^^ expected `i32`, found `usize` + | | + | expected because this is `i32` | help: you can convert a `usize` to an `i32` and panic if the converted value doesn't fit | @@ -1256,7 +1484,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:281:17 | LL | x_i64 > x_u8; - | ^^^^ expected `i64`, found `u8` + | ----- ^^^^ expected `i64`, found `u8` + | | + | expected because this is `i64` | help: you can convert a `u8` to an `i64` | @@ -1267,7 +1497,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:283:17 | LL | x_i64 > x_u16; - | ^^^^^ expected `i64`, found `u16` + | ----- ^^^^^ expected `i64`, found `u16` + | | + | expected because this is `i64` | help: you can convert a `u16` to an `i64` | @@ -1278,7 +1510,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:285:17 | LL | x_i64 > x_u32; - | ^^^^^ expected `i64`, found `u32` + | ----- ^^^^^ expected `i64`, found `u32` + | | + | expected because this is `i64` | help: you can convert a `u32` to an `i64` | @@ -1289,7 +1523,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:287:17 | LL | x_i64 > x_u64; - | ^^^^^ expected `i64`, found `u64` + | ----- ^^^^^ expected `i64`, found `u64` + | | + | expected because this is `i64` | help: you can convert a `u64` to an `i64` and panic if the converted value doesn't fit | @@ -1300,7 +1536,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:289:17 | LL | x_i64 > x_u128; - | ^^^^^^ expected `i64`, found `u128` + | ----- ^^^^^^ expected `i64`, found `u128` + | | + | expected because this is `i64` | help: you can convert a `u128` to an `i64` and panic if the converted value doesn't fit | @@ -1311,7 +1549,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:291:17 | LL | x_i64 > x_usize; - | ^^^^^^^ expected `i64`, found `usize` + | ----- ^^^^^^^ expected `i64`, found `usize` + | | + | expected because this is `i64` | help: you can convert a `usize` to an `i64` and panic if the converted value doesn't fit | @@ -1322,7 +1562,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:294:18 | LL | x_i128 > x_u8; - | ^^^^ expected `i128`, found `u8` + | ------ ^^^^ expected `i128`, found `u8` + | | + | expected because this is `i128` | help: you can convert a `u8` to an `i128` | @@ -1333,7 +1575,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:296:18 | LL | x_i128 > x_u16; - | ^^^^^ expected `i128`, found `u16` + | ------ ^^^^^ expected `i128`, found `u16` + | | + | expected because this is `i128` | help: you can convert a `u16` to an `i128` | @@ -1344,7 +1588,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:298:18 | LL | x_i128 > x_u32; - | ^^^^^ expected `i128`, found `u32` + | ------ ^^^^^ expected `i128`, found `u32` + | | + | expected because this is `i128` | help: you can convert a `u32` to an `i128` | @@ -1355,7 +1601,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:300:18 | LL | x_i128 > x_u64; - | ^^^^^ expected `i128`, found `u64` + | ------ ^^^^^ expected `i128`, found `u64` + | | + | expected because this is `i128` | help: you can convert a `u64` to an `i128` | @@ -1366,7 +1614,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:302:18 | LL | x_i128 > x_u128; - | ^^^^^^ expected `i128`, found `u128` + | ------ ^^^^^^ expected `i128`, found `u128` + | | + | expected because this is `i128` | help: you can convert a `u128` to an `i128` and panic if the converted value doesn't fit | @@ -1377,7 +1627,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:304:18 | LL | x_i128 > x_usize; - | ^^^^^^^ expected `i128`, found `usize` + | ------ ^^^^^^^ expected `i128`, found `usize` + | | + | expected because this is `i128` | help: you can convert a `usize` to an `i128` and panic if the converted value doesn't fit | @@ -1388,7 +1640,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:307:19 | LL | x_isize > x_u8; - | ^^^^ expected `isize`, found `u8` + | ------- ^^^^ expected `isize`, found `u8` + | | + | expected because this is `isize` | help: you can convert a `u8` to an `isize` | @@ -1399,7 +1653,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:309:19 | LL | x_isize > x_u16; - | ^^^^^ expected `isize`, found `u16` + | ------- ^^^^^ expected `isize`, found `u16` + | | + | expected because this is `isize` | help: you can convert a `u16` to an `isize` and panic if the converted value doesn't fit | @@ -1410,7 +1666,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:311:19 | LL | x_isize > x_u32; - | ^^^^^ expected `isize`, found `u32` + | ------- ^^^^^ expected `isize`, found `u32` + | | + | expected because this is `isize` | help: you can convert a `u32` to an `isize` and panic if the converted value doesn't fit | @@ -1421,7 +1679,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:313:19 | LL | x_isize > x_u64; - | ^^^^^ expected `isize`, found `u64` + | ------- ^^^^^ expected `isize`, found `u64` + | | + | expected because this is `isize` | help: you can convert a `u64` to an `isize` and panic if the converted value doesn't fit | @@ -1432,7 +1692,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:315:19 | LL | x_isize > x_u128; - | ^^^^^^ expected `isize`, found `u128` + | ------- ^^^^^^ expected `isize`, found `u128` + | | + | expected because this is `isize` | help: you can convert a `u128` to an `isize` and panic if the converted value doesn't fit | @@ -1443,7 +1705,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-binop.rs:317:19 | LL | x_isize > x_usize; - | ^^^^^^^ expected `isize`, found `usize` + | ------- ^^^^^^^ expected `isize`, found `usize` + | | + | expected because this is `isize` | help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit | diff --git a/src/test/ui/numeric/numeric-cast-no-fix.stderr b/src/test/ui/numeric/numeric-cast-no-fix.stderr index e4843206de1..c244e479d24 100644 --- a/src/test/ui/numeric/numeric-cast-no-fix.stderr +++ b/src/test/ui/numeric/numeric-cast-no-fix.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:10:15 | LL | x_usize > -1_isize; - | ^^^^^^^^ expected `usize`, found `isize` + | ------- ^^^^^^^^ expected `usize`, found `isize` + | | + | expected because this is `usize` | = note: `-1_isize` cannot fit into type `usize` @@ -10,7 +12,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:12:14 | LL | x_u128 > -1_isize; - | ^^^^^^^^ expected `u128`, found `isize` + | ------ ^^^^^^^^ expected `u128`, found `isize` + | | + | expected because this is `u128` | = note: `-1_isize` cannot fit into type `u128` @@ -18,7 +22,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:14:13 | LL | x_u64 > -1_isize; - | ^^^^^^^^ expected `u64`, found `isize` + | ----- ^^^^^^^^ expected `u64`, found `isize` + | | + | expected because this is `u64` | = note: `-1_isize` cannot fit into type `u64` @@ -26,7 +32,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:16:13 | LL | x_u32 > -1_isize; - | ^^^^^^^^ expected `u32`, found `isize` + | ----- ^^^^^^^^ expected `u32`, found `isize` + | | + | expected because this is `u32` | = note: `-1_isize` cannot fit into type `u32` @@ -34,7 +42,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:18:13 | LL | x_u16 > -1_isize; - | ^^^^^^^^ expected `u16`, found `isize` + | ----- ^^^^^^^^ expected `u16`, found `isize` + | | + | expected because this is `u16` | = note: `-1_isize` cannot fit into type `u16` @@ -42,7 +52,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:20:12 | LL | x_u8 > -1_isize; - | ^^^^^^^^ expected `u8`, found `isize` + | ---- ^^^^^^^^ expected `u8`, found `isize` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `isize`, matching the type of `-1_isize` | @@ -53,7 +65,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:23:15 | LL | x_usize > -1_i128; - | ^^^^^^^ expected `usize`, found `i128` + | ------- ^^^^^^^ expected `usize`, found `i128` + | | + | expected because this is `usize` | = note: `-1_i128` cannot fit into type `usize` @@ -61,7 +75,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:25:14 | LL | x_u128 > -1_i128; - | ^^^^^^^ expected `u128`, found `i128` + | ------ ^^^^^^^ expected `u128`, found `i128` + | | + | expected because this is `u128` | = note: `-1_i128` cannot fit into type `u128` @@ -69,7 +85,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:27:13 | LL | x_u64 > -1_i128; - | ^^^^^^^ expected `u64`, found `i128` + | ----- ^^^^^^^ expected `u64`, found `i128` + | | + | expected because this is `u64` | help: you can convert `x_u64` from `u64` to `i128`, matching the type of `-1_i128` | @@ -80,7 +98,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:29:13 | LL | x_u32 > -1_i128; - | ^^^^^^^ expected `u32`, found `i128` + | ----- ^^^^^^^ expected `u32`, found `i128` + | | + | expected because this is `u32` | help: you can convert `x_u32` from `u32` to `i128`, matching the type of `-1_i128` | @@ -91,7 +111,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:31:13 | LL | x_u16 > -1_i128; - | ^^^^^^^ expected `u16`, found `i128` + | ----- ^^^^^^^ expected `u16`, found `i128` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `i128`, matching the type of `-1_i128` | @@ -102,7 +124,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:33:12 | LL | x_u8 > -1_i128; - | ^^^^^^^ expected `u8`, found `i128` + | ---- ^^^^^^^ expected `u8`, found `i128` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `i128`, matching the type of `-1_i128` | @@ -113,7 +137,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:36:15 | LL | x_usize > -1_i64; - | ^^^^^^ expected `usize`, found `i64` + | ------- ^^^^^^ expected `usize`, found `i64` + | | + | expected because this is `usize` | = note: `-1_i64` cannot fit into type `usize` @@ -121,7 +147,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:38:14 | LL | x_u128 > -1_i64; - | ^^^^^^ expected `u128`, found `i64` + | ------ ^^^^^^ expected `u128`, found `i64` + | | + | expected because this is `u128` | = note: `-1_i64` cannot fit into type `u128` @@ -129,7 +157,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:40:13 | LL | x_u64 > -1_i64; - | ^^^^^^ expected `u64`, found `i64` + | ----- ^^^^^^ expected `u64`, found `i64` + | | + | expected because this is `u64` | = note: `-1_i64` cannot fit into type `u64` @@ -137,7 +167,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:42:13 | LL | x_u32 > -1_i64; - | ^^^^^^ expected `u32`, found `i64` + | ----- ^^^^^^ expected `u32`, found `i64` + | | + | expected because this is `u32` | help: you can convert `x_u32` from `u32` to `i64`, matching the type of `-1_i64` | @@ -148,7 +180,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:44:13 | LL | x_u16 > -1_i64; - | ^^^^^^ expected `u16`, found `i64` + | ----- ^^^^^^ expected `u16`, found `i64` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `i64`, matching the type of `-1_i64` | @@ -159,7 +193,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:46:12 | LL | x_u8 > -1_i64; - | ^^^^^^ expected `u8`, found `i64` + | ---- ^^^^^^ expected `u8`, found `i64` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `i64`, matching the type of `-1_i64` | @@ -170,7 +206,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:49:15 | LL | x_usize > -1_i32; - | ^^^^^^ expected `usize`, found `i32` + | ------- ^^^^^^ expected `usize`, found `i32` + | | + | expected because this is `usize` | = note: `-1_i32` cannot fit into type `usize` @@ -178,7 +216,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:51:14 | LL | x_u128 > -1_i32; - | ^^^^^^ expected `u128`, found `i32` + | ------ ^^^^^^ expected `u128`, found `i32` + | | + | expected because this is `u128` | = note: `-1_i32` cannot fit into type `u128` @@ -186,7 +226,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:53:13 | LL | x_u64 > -1_i32; - | ^^^^^^ expected `u64`, found `i32` + | ----- ^^^^^^ expected `u64`, found `i32` + | | + | expected because this is `u64` | = note: `-1_i32` cannot fit into type `u64` @@ -194,7 +236,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:55:13 | LL | x_u32 > -1_i32; - | ^^^^^^ expected `u32`, found `i32` + | ----- ^^^^^^ expected `u32`, found `i32` + | | + | expected because this is `u32` | = note: `-1_i32` cannot fit into type `u32` @@ -202,7 +246,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:57:13 | LL | x_u16 > -1_i32; - | ^^^^^^ expected `u16`, found `i32` + | ----- ^^^^^^ expected `u16`, found `i32` + | | + | expected because this is `u16` | help: you can convert `x_u16` from `u16` to `i32`, matching the type of `-1_i32` | @@ -213,7 +259,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:59:12 | LL | x_u8 > -1_i32; - | ^^^^^^ expected `u8`, found `i32` + | ---- ^^^^^^ expected `u8`, found `i32` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `i32`, matching the type of `-1_i32` | @@ -224,7 +272,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:62:15 | LL | x_usize > -1_i16; - | ^^^^^^ expected `usize`, found `i16` + | ------- ^^^^^^ expected `usize`, found `i16` + | | + | expected because this is `usize` | = note: `-1_i16` cannot fit into type `usize` @@ -232,7 +282,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:64:14 | LL | x_u128 > -1_i16; - | ^^^^^^ expected `u128`, found `i16` + | ------ ^^^^^^ expected `u128`, found `i16` + | | + | expected because this is `u128` | = note: `-1_i16` cannot fit into type `u128` @@ -240,7 +292,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:66:13 | LL | x_u64 > -1_i16; - | ^^^^^^ expected `u64`, found `i16` + | ----- ^^^^^^ expected `u64`, found `i16` + | | + | expected because this is `u64` | = note: `-1_i16` cannot fit into type `u64` @@ -248,7 +302,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:68:13 | LL | x_u32 > -1_i16; - | ^^^^^^ expected `u32`, found `i16` + | ----- ^^^^^^ expected `u32`, found `i16` + | | + | expected because this is `u32` | = note: `-1_i16` cannot fit into type `u32` @@ -256,7 +312,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:70:13 | LL | x_u16 > -1_i16; - | ^^^^^^ expected `u16`, found `i16` + | ----- ^^^^^^ expected `u16`, found `i16` + | | + | expected because this is `u16` | = note: `-1_i16` cannot fit into type `u16` @@ -264,7 +322,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:72:12 | LL | x_u8 > -1_i16; - | ^^^^^^ expected `u8`, found `i16` + | ---- ^^^^^^ expected `u8`, found `i16` + | | + | expected because this is `u8` | help: you can convert `x_u8` from `u8` to `i16`, matching the type of `-1_i16` | @@ -275,7 +335,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:75:15 | LL | x_usize > -1_i8; - | ^^^^^ expected `usize`, found `i8` + | ------- ^^^^^ expected `usize`, found `i8` + | | + | expected because this is `usize` | = note: `-1_i8` cannot fit into type `usize` @@ -283,7 +345,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:77:14 | LL | x_u128 > -1_i8; - | ^^^^^ expected `u128`, found `i8` + | ------ ^^^^^ expected `u128`, found `i8` + | | + | expected because this is `u128` | = note: `-1_i8` cannot fit into type `u128` @@ -291,7 +355,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:79:13 | LL | x_u64 > -1_i8; - | ^^^^^ expected `u64`, found `i8` + | ----- ^^^^^ expected `u64`, found `i8` + | | + | expected because this is `u64` | = note: `-1_i8` cannot fit into type `u64` @@ -299,7 +365,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:81:13 | LL | x_u32 > -1_i8; - | ^^^^^ expected `u32`, found `i8` + | ----- ^^^^^ expected `u32`, found `i8` + | | + | expected because this is `u32` | = note: `-1_i8` cannot fit into type `u32` @@ -307,7 +375,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:83:13 | LL | x_u16 > -1_i8; - | ^^^^^ expected `u16`, found `i8` + | ----- ^^^^^ expected `u16`, found `i8` + | | + | expected because this is `u16` | = note: `-1_i8` cannot fit into type `u16` @@ -315,7 +385,9 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:85:12 | LL | x_u8 > -1_i8; - | ^^^^^ expected `u8`, found `i8` + | ---- ^^^^^ expected `u8`, found `i8` + | | + | expected because this is `u8` | = note: `-1_i8` cannot fit into type `u8` diff --git a/src/test/ui/on-unimplemented/sum.rs b/src/test/ui/on-unimplemented/sum.rs new file mode 100644 index 00000000000..4f1c521d9fe --- /dev/null +++ b/src/test/ui/on-unimplemented/sum.rs @@ -0,0 +1,9 @@ +// <https://github.com/rust-lang/rust/issues/105184> + +fn main() { + vec![(), ()].iter().sum::<i32>(); + //~^ ERROR + + vec![(), ()].iter().product::<i32>(); + //~^ ERROR +} diff --git a/src/test/ui/on-unimplemented/sum.stderr b/src/test/ui/on-unimplemented/sum.stderr new file mode 100644 index 00000000000..0c99e63f0e5 --- /dev/null +++ b/src/test/ui/on-unimplemented/sum.stderr @@ -0,0 +1,39 @@ +error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()` + --> $DIR/sum.rs:4:5 + | +LL | vec![(), ()].iter().sum::<i32>(); + | ^^^^^^^^^^^^^^^^^^^ --- required by a bound introduced by this call + | | + | value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>` + | + = help: the trait `Sum<&()>` is not implemented for `i32` + = help: the following other types implement trait `Sum<A>`: + <i32 as Sum<&'a i32>> + <i32 as Sum> +note: required by a bound in `std::iter::Iterator::sum` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | +LL | S: Sum<Self::Item>, + | ^^^^^^^^^^^^^^^ required by this bound in `std::iter::Iterator::sum` + +error[E0277]: a value of type `i32` cannot be made by multiplying all elements of type `&()` from an iterator + --> $DIR/sum.rs:7:5 + | +LL | vec![(), ()].iter().product::<i32>(); + | ^^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `i32` cannot be made by multiplying all elements from a `std::iter::Iterator<Item=&()>` + | + = help: the trait `Product<&()>` is not implemented for `i32` + = help: the following other types implement trait `Product<A>`: + <i32 as Product<&'a i32>> + <i32 as Product> +note: required by a bound in `std::iter::Iterator::product` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | +LL | P: Product<Self::Item>, + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `std::iter::Iterator::product` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/parser/bare-struct-body.stderr b/src/test/ui/parser/bare-struct-body.stderr index c77992b2c34..7d17ea59647 100644 --- a/src/test/ui/parser/bare-struct-body.stderr +++ b/src/test/ui/parser/bare-struct-body.stderr @@ -34,7 +34,9 @@ error[E0308]: mismatched types --> $DIR/bare-struct-body.rs:11:14 | LL | x.val == 42; - | ^^ expected `()`, found integer + | ----- ^^ expected `()`, found integer + | | + | expected because this is `()` error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/chained-comparison-suggestion.stderr b/src/test/ui/parser/chained-comparison-suggestion.stderr index 694b0b6eb02..ae243816d7c 100644 --- a/src/test/ui/parser/chained-comparison-suggestion.stderr +++ b/src/test/ui/parser/chained-comparison-suggestion.stderr @@ -123,37 +123,49 @@ error[E0308]: mismatched types --> $DIR/chained-comparison-suggestion.rs:4:14 | LL | 1 < 2 <= 3; - | ^ expected `bool`, found integer + | ----- ^ expected `bool`, found integer + | | + | expected because this is `bool` error[E0308]: mismatched types --> $DIR/chained-comparison-suggestion.rs:13:14 | LL | 1 <= 2 < 3; - | ^ expected `bool`, found integer + | ------ ^ expected `bool`, found integer + | | + | expected because this is `bool` error[E0308]: mismatched types --> $DIR/chained-comparison-suggestion.rs:18:15 | LL | 1 <= 2 <= 3; - | ^ expected `bool`, found integer + | ------ ^ expected `bool`, found integer + | | + | expected because this is `bool` error[E0308]: mismatched types --> $DIR/chained-comparison-suggestion.rs:23:14 | LL | 1 > 2 >= 3; - | ^ expected `bool`, found integer + | ----- ^ expected `bool`, found integer + | | + | expected because this is `bool` error[E0308]: mismatched types --> $DIR/chained-comparison-suggestion.rs:36:15 | LL | 1 >= 2 >= 3; - | ^ expected `bool`, found integer + | ------ ^ expected `bool`, found integer + | | + | expected because this is `bool` error[E0308]: mismatched types --> $DIR/chained-comparison-suggestion.rs:49:15 | LL | 1 == 2 == 3; - | ^ expected `bool`, found integer + | ------ ^ expected `bool`, found integer + | | + | expected because this is `bool` error: aborting due to 17 previous errors diff --git a/src/test/ui/pptypedef.stderr b/src/test/ui/pptypedef.stderr index 49895f3db4d..08b90b365e3 100644 --- a/src/test/ui/pptypedef.stderr +++ b/src/test/ui/pptypedef.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/pptypedef.rs:4:37 | LL | let_in(3u32, |i| { assert!(i == 3i32); }); - | ^^^^ expected `u32`, found `i32` + | - ^^^^ expected `u32`, found `i32` + | | + | expected because this is `u32` | help: change the type of the numeric literal from `i32` to `u32` | @@ -13,7 +15,9 @@ error[E0308]: mismatched types --> $DIR/pptypedef.rs:8:37 | LL | let_in(3i32, |i| { assert!(i == 3u32); }); - | ^^^^ expected `i32`, found `u32` + | - ^^^^ expected `i32`, found `u32` + | | + | expected because this is `i32` | help: change the type of the numeric literal from `u32` to `i32` | diff --git a/src/test/ui/print_type_sizes/async.rs b/src/test/ui/print_type_sizes/async.rs new file mode 100644 index 00000000000..3491ad5afbc --- /dev/null +++ b/src/test/ui/print_type_sizes/async.rs @@ -0,0 +1,19 @@ +// compile-flags: -Z print-type-sizes +// edition:2021 +// build-pass +// ignore-pass + +#![feature(start)] + +async fn wait() {} + +async fn test(arg: [u8; 8192]) { + wait().await; + drop(arg); +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _ = test([0; 8192]); + 0 +} diff --git a/src/test/ui/print_type_sizes/async.stdout b/src/test/ui/print_type_sizes/async.stdout new file mode 100644 index 00000000000..94ad09ef296 --- /dev/null +++ b/src/test/ui/print_type_sizes/async.stdout @@ -0,0 +1,34 @@ +print-type-size type: `[async fn body@$DIR/async.rs:10:32: 13:2]`: 16386 bytes, alignment: 1 bytes +print-type-size discriminant: 1 bytes +print-type-size variant `Suspend0`: 16385 bytes +print-type-size field `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size field `.arg`: 8192 bytes +print-type-size field `.__awaitee`: 1 bytes +print-type-size variant `Unresumed`: 8192 bytes +print-type-size field `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size variant `Returned`: 8192 bytes +print-type-size field `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size variant `Panicked`: 8192 bytes +print-type-size field `.arg`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes +print-type-size field `.value`: 8192 bytes +print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes +print-type-size variant `MaybeUninit`: 8192 bytes +print-type-size field `.uninit`: 0 bytes +print-type-size field `.value`: 8192 bytes +print-type-size type: `[async fn body@$DIR/async.rs:8:17: 8:19]`: 1 bytes, alignment: 1 bytes +print-type-size discriminant: 1 bytes +print-type-size variant `Unresumed`: 0 bytes +print-type-size variant `Returned`: 0 bytes +print-type-size variant `Panicked`: 0 bytes +print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes +print-type-size field `.value`: 1 bytes +print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes +print-type-size variant `MaybeUninit`: 1 bytes +print-type-size field `.uninit`: 0 bytes +print-type-size field `.value`: 1 bytes +print-type-size type: `std::task::Poll<()>`: 1 bytes, alignment: 1 bytes +print-type-size discriminant: 1 bytes +print-type-size variant `Ready`: 0 bytes +print-type-size field `.0`: 0 bytes +print-type-size variant `Pending`: 0 bytes diff --git a/src/test/ui/print_type_sizes/generator.rs b/src/test/ui/print_type_sizes/generator.rs new file mode 100644 index 00000000000..a46db612104 --- /dev/null +++ b/src/test/ui/print_type_sizes/generator.rs @@ -0,0 +1,20 @@ +// compile-flags: -Z print-type-sizes +// build-pass +// ignore-pass + +#![feature(start, generators, generator_trait)] + +use std::ops::Generator; + +fn generator<const C: usize>(array: [u8; C]) -> impl Generator<Yield = (), Return = ()> { + move |()| { + yield (); + let _ = array; + } +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _ = generator([0; 8192]); + 0 +} diff --git a/src/test/ui/print_type_sizes/generator.stdout b/src/test/ui/print_type_sizes/generator.stdout new file mode 100644 index 00000000000..28d4a6e6cff --- /dev/null +++ b/src/test/ui/print_type_sizes/generator.stdout @@ -0,0 +1,10 @@ +print-type-size type: `[generator@$DIR/generator.rs:10:5: 10:14]`: 8193 bytes, alignment: 1 bytes +print-type-size discriminant: 1 bytes +print-type-size variant `Unresumed`: 8192 bytes +print-type-size field `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size variant `Returned`: 8192 bytes +print-type-size field `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size variant `Panicked`: 8192 bytes +print-type-size field `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes +print-type-size variant `Suspend0`: 8192 bytes +print-type-size field `.array`: 8192 bytes, offset: 0 bytes, alignment: 1 bytes diff --git a/src/test/ui/proc-macro/attr-invalid-exprs.stderr b/src/test/ui/proc-macro/attr-invalid-exprs.stderr index bcb54df0eca..f96939bb6ef 100644 --- a/src/test/ui/proc-macro/attr-invalid-exprs.stderr +++ b/src/test/ui/proc-macro/attr-invalid-exprs.stderr @@ -8,21 +8,25 @@ error: macro expansion ignores token `,` and any following --> $DIR/attr-invalid-exprs.rs:15:13 | LL | let _ = #[duplicate] "Hello, world!"; - | ^^^^^^^^^^^^- help: you might be missing a semicolon here: `;` - | | - | caused by the macro expansion here + | ^^^^^^^^^^^^ caused by the macro expansion here | = note: the usage of `duplicate!` is likely invalid in expression context +help: you might be missing a semicolon here + | +LL | let _ = #[duplicate]; "Hello, world!"; + | + error: macro expansion ignores token `,` and any following --> $DIR/attr-invalid-exprs.rs:24:9 | LL | #[duplicate] - | ^^^^^^^^^^^^- help: you might be missing a semicolon here: `;` - | | - | caused by the macro expansion here + | ^^^^^^^^^^^^ caused by the macro expansion here | = note: the usage of `duplicate!` is likely invalid in expression context +help: you might be missing a semicolon here + | +LL | #[duplicate]; + | + error: aborting due to 3 previous errors diff --git a/src/test/ui/proc-macro/attribute.rs b/src/test/ui/proc-macro/attribute.rs index 5531b323621..9e40e4d9ba6 100644 --- a/src/test/ui/proc-macro/attribute.rs +++ b/src/test/ui/proc-macro/attribute.rs @@ -53,19 +53,19 @@ pub fn foo11(input: TokenStream) -> TokenStream { input } pub fn foo12(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d13, attributes("a"))] -//~^ ERROR: not a meta item +//~^ ERROR: attribute must be a meta item, not a literal pub fn foo13(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d14, attributes(a = ""))] -//~^ ERROR: must only be one word +//~^ ERROR: attribute must only be a single word pub fn foo14(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d15, attributes(m::a))] -//~^ ERROR: must only be one word +//~^ ERROR: attribute must only be a single word pub fn foo15(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d16, attributes(a(b)))] -//~^ ERROR: must only be one word +//~^ ERROR: attribute must only be a single word pub fn foo16(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d17, attributes(self))] diff --git a/src/test/ui/proc-macro/attribute.stderr b/src/test/ui/proc-macro/attribute.stderr index 021e7cad09b..3269aaf7f91 100644 --- a/src/test/ui/proc-macro/attribute.stderr +++ b/src/test/ui/proc-macro/attribute.stderr @@ -70,25 +70,25 @@ error: attribute must be of form: `attributes(foo, bar)` LL | #[proc_macro_derive(d12, attributes)] | ^^^^^^^^^^ -error: not a meta item +error: attribute must be a meta item, not a literal --> $DIR/attribute.rs:55:37 | LL | #[proc_macro_derive(d13, attributes("a"))] | ^^^ -error: must only be one word +error: attribute must only be a single word --> $DIR/attribute.rs:59:37 | LL | #[proc_macro_derive(d14, attributes(a = ""))] | ^^^^^^ -error: must only be one word +error: attribute must only be a single word --> $DIR/attribute.rs:63:37 | LL | #[proc_macro_derive(d15, attributes(m::a))] | ^^^^ -error: must only be one word +error: attribute must only be a single word --> $DIR/attribute.rs:67:37 | LL | #[proc_macro_derive(d16, attributes(a(b)))] diff --git a/src/test/ui/proc-macro/expand-expr.stderr b/src/test/ui/proc-macro/expand-expr.stderr index c6c4695fd9c..0004f2fe17f 100644 --- a/src/test/ui/proc-macro/expand-expr.stderr +++ b/src/test/ui/proc-macro/expand-expr.stderr @@ -26,21 +26,25 @@ error: macro expansion ignores token `hello` and any following --> $DIR/expand-expr.rs:115:47 | LL | expand_expr_is!("string", echo_tts!("string"; hello)); - | --------------------^^^^^-- help: you might be missing a semicolon here: `;` - | | - | caused by the macro expansion here + | --------------------^^^^^- caused by the macro expansion here | = note: the usage of `echo_tts!` is likely invalid in expression context +help: you might be missing a semicolon here + | +LL | expand_expr_is!("string", echo_tts!("string"; hello);); + | + error: macro expansion ignores token `;` and any following --> $DIR/expand-expr.rs:116:44 | LL | expand_expr_is!("string", echo_pm!("string"; hello)); - | -----------------^-------- help: you might be missing a semicolon here: `;` - | | - | caused by the macro expansion here + | -----------------^------- caused by the macro expansion here | = note: the usage of `echo_pm!` is likely invalid in expression context +help: you might be missing a semicolon here + | +LL | expand_expr_is!("string", echo_pm!("string"; hello);); + | + error: recursion limit reached while expanding `recursive_expand!` --> $DIR/expand-expr.rs:124:16 diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr index 4d00a708313..dde8ad1b6b3 100644 --- a/src/test/ui/recursion/issue-83150.stderr +++ b/src/test/ui/recursion/issue-83150.stderr @@ -12,7 +12,7 @@ LL | func(&mut iter.map(|x| x + 1)) error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>: Iterator` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) - = note: required for `&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>` to implement `Iterator` + = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>, ...>, ...>, ...>` to implement `Iterator` = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type-hash.txt' error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/regions/issue-102374.rs b/src/test/ui/regions/issue-102374.rs index e0a1164211a..fd71248d9cb 100644 --- a/src/test/ui/regions/issue-102374.rs +++ b/src/test/ui/regions/issue-102374.rs @@ -1,3 +1,4 @@ +// normalize-stderr-test: "long-type-\d+" -> "long-type-hash" use std::cell::Cell; #[rustfmt::skip] diff --git a/src/test/ui/regions/issue-102374.stderr b/src/test/ui/regions/issue-102374.stderr index 31b855c36be..157850693ab 100644 --- a/src/test/ui/regions/issue-102374.stderr +++ b/src/test/ui/regions/issue-102374.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-102374.rs:16:5 + --> $DIR/issue-102374.rs:17:5 | LL | ) -> i32 { | --- expected `i32` because of return type @@ -7,7 +7,8 @@ LL | f | ^ expected `i32`, found fn pointer | = note: expected type `i32` - found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<(&'z1 i32, &'a i32, &'b i32, &'c i32, &'d i32, &'e i32, &'f i32, &'g i32, &'h i32, &'i i32, &'j i32, &'k i32, &'l i32, &'m i32, &'n i32, &'o i32, &'p i32, &'q i32, &'r i32, &'s i32, &'t i32, &'u i32, &'v i32, &'w i32, &'x i32, &'y i32, &'z i32, &'z0 i32)>)` + found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<...>)` + the full type name has been written to '$TEST_BUILD_DIR/regions/issue-102374/issue-102374.long-type-hash.txt' error: aborting due to previous error diff --git a/src/test/ui/span/issue-71363.rs b/src/test/ui/span/issue-71363.rs index bbb4a93623b..f187d0efa84 100644 --- a/src/test/ui/span/issue-71363.rs +++ b/src/test/ui/span/issue-71363.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z simulate-remapped-rust-src-base=/rustc/xyz -Z translate-remapped-path-to-local-path=no -Z ui-testing=no +// compile-flags: -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ui-testing=no struct MyError; impl std::error::Error for MyError {} diff --git a/src/test/ui/span/issue-71363.stderr b/src/test/ui/span/issue-71363.stderr index 04e2b46c317..6c7ea007ee0 100644 --- a/src/test/ui/span/issue-71363.stderr +++ b/src/test/ui/span/issue-71363.stderr @@ -7,6 +7,7 @@ error[E0277]: `MyError` doesn't implement `std::fmt::Display` = help: the trait `std::fmt::Display` is not implemented for `MyError` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead note: required by a bound in `std::error::Error` + --> $SRC_DIR/core/src/error.rs:LL:COL error[E0277]: `MyError` doesn't implement `Debug` --> $DIR/issue-71363.rs:4:6 @@ -17,6 +18,7 @@ error[E0277]: `MyError` doesn't implement `Debug` = help: the trait `Debug` is not implemented for `MyError` = note: add `#[derive(Debug)]` to `MyError` or manually `impl Debug for MyError` note: required by a bound in `std::error::Error` + --> $SRC_DIR/core/src/error.rs:LL:COL help: consider annotating `MyError` with `#[derive(Debug)]` | 3 | #[derive(Debug)] diff --git a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr index 4e21d36014c..bc6342004f4 100644 --- a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr +++ b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr @@ -2,7 +2,10 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-try_into-in-macros.rs:2:5 | LL | assert_eq!(10u64, 10usize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `usize` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected `u64`, found `usize` + | expected because this is `u64` | = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/suggestions/option-to-bool.stderr b/src/test/ui/suggestions/option-to-bool.stderr index 57a934b8342..4050c7be82a 100644 --- a/src/test/ui/suggestions/option-to-bool.stderr +++ b/src/test/ui/suggestions/option-to-bool.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/option-to-bool.rs:4:16 | LL | if true && x {} - | ^ expected `bool`, found enum `Option` + | ---- ^ expected `bool`, found enum `Option` + | | + | expected because this is `bool` | = note: expected type `bool` found enum `Option<i32>` diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs index 56e8fcff0fc..8db5fa615c0 100644 --- a/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs +++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs @@ -1,15 +1,15 @@ #![feature(rustc_attrs)] #[rustc_must_implement_one_of(a, a)] -//~^ Functions names are duplicated +//~^ functions names are duplicated trait Trait { fn a() {} } #[rustc_must_implement_one_of(b, a, a, c, b, c)] -//~^ Functions names are duplicated -//~| Functions names are duplicated -//~| Functions names are duplicated +//~^ functions names are duplicated +//~| functions names are duplicated +//~| functions names are duplicated trait Trait1 { fn a() {} fn b() {} diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr index 777beba6182..cd1476a6eb8 100644 --- a/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr +++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr @@ -1,34 +1,34 @@ -error: Functions names are duplicated +error: functions names are duplicated --> $DIR/rustc_must_implement_one_of_duplicates.rs:3:31 | LL | #[rustc_must_implement_one_of(a, a)] | ^ ^ | - = note: All `#[rustc_must_implement_one_of]` arguments must be unique + = note: all `#[rustc_must_implement_one_of]` arguments must be unique -error: Functions names are duplicated +error: functions names are duplicated --> $DIR/rustc_must_implement_one_of_duplicates.rs:9:34 | LL | #[rustc_must_implement_one_of(b, a, a, c, b, c)] | ^ ^ | - = note: All `#[rustc_must_implement_one_of]` arguments must be unique + = note: all `#[rustc_must_implement_one_of]` arguments must be unique -error: Functions names are duplicated +error: functions names are duplicated --> $DIR/rustc_must_implement_one_of_duplicates.rs:9:31 | LL | #[rustc_must_implement_one_of(b, a, a, c, b, c)] | ^ ^ | - = note: All `#[rustc_must_implement_one_of]` arguments must be unique + = note: all `#[rustc_must_implement_one_of]` arguments must be unique -error: Functions names are duplicated +error: functions names are duplicated --> $DIR/rustc_must_implement_one_of_duplicates.rs:9:40 | LL | #[rustc_must_implement_one_of(b, a, a, c, b, c)] | ^ ^ | - = note: All `#[rustc_must_implement_one_of]` arguments must be unique + = note: all `#[rustc_must_implement_one_of]` arguments must be unique error: aborting due to 4 previous errors diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs index 1f896da94db..b1b91966c8d 100644 --- a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs +++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs @@ -1,12 +1,12 @@ #![feature(rustc_attrs)] #[rustc_must_implement_one_of(a, b)] -//~^ Function not found in this trait -//~| Function not found in this trait +//~^ function not found in this trait +//~| function not found in this trait trait Tr0 {} #[rustc_must_implement_one_of(a, b)] -//~^ Function not found in this trait +//~^ function not found in this trait trait Tr1 { fn a() {} } @@ -23,16 +23,16 @@ trait Tr3 {} #[rustc_must_implement_one_of(A, B)] trait Tr4 { - const A: u8 = 1; //~ Not a function + const A: u8 = 1; //~ not a function - type B; //~ Not a function + type B; //~ not a function } #[rustc_must_implement_one_of(a, b)] trait Tr5 { - fn a(); //~ This function doesn't have a default implementation + fn a(); //~ function doesn't have a default implementation - fn b(); //~ This function doesn't have a default implementation + fn b(); //~ function doesn't have a default implementation } #[rustc_must_implement_one_of(abc, xyz)] diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr index 869184f0d1a..38e692521ca 100644 --- a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr +++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr @@ -22,19 +22,19 @@ LL | LL | struct Struct {} | ---------------- not a trait -error: Function not found in this trait +error: function not found in this trait --> $DIR/rustc_must_implement_one_of_misuse.rs:3:31 | LL | #[rustc_must_implement_one_of(a, b)] | ^ -error: Function not found in this trait +error: function not found in this trait --> $DIR/rustc_must_implement_one_of_misuse.rs:3:34 | LL | #[rustc_must_implement_one_of(a, b)] | ^ -error: Function not found in this trait +error: function not found in this trait --> $DIR/rustc_must_implement_one_of_misuse.rs:8:34 | LL | #[rustc_must_implement_one_of(a, b)] @@ -46,7 +46,7 @@ error: the `#[rustc_must_implement_one_of]` attribute must be used with at least LL | #[rustc_must_implement_one_of(a)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Not a function +error: not a function --> $DIR/rustc_must_implement_one_of_misuse.rs:26:5 | LL | const A: u8 = 1; @@ -57,9 +57,9 @@ note: required by this annotation | LL | #[rustc_must_implement_one_of(A, B)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: All `#[rustc_must_implement_one_of]` arguments must be associated function names + = note: all `#[rustc_must_implement_one_of]` arguments must be associated function names -error: Not a function +error: not a function --> $DIR/rustc_must_implement_one_of_misuse.rs:28:5 | LL | type B; @@ -70,9 +70,9 @@ note: required by this annotation | LL | #[rustc_must_implement_one_of(A, B)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: All `#[rustc_must_implement_one_of]` arguments must be associated function names + = note: all `#[rustc_must_implement_one_of]` arguments must be associated function names -error: This function doesn't have a default implementation +error: function doesn't have a default implementation --> $DIR/rustc_must_implement_one_of_misuse.rs:33:5 | LL | fn a(); @@ -84,7 +84,7 @@ note: required by this annotation LL | #[rustc_must_implement_one_of(a, b)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: This function doesn't have a default implementation +error: function doesn't have a default implementation --> $DIR/rustc_must_implement_one_of_misuse.rs:35:5 | LL | fn b(); diff --git a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr index a74d2524996..1f18c5daf66 100644 --- a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr +++ b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr @@ -17,7 +17,7 @@ error[E0275]: overflow evaluating the requirement `(): Sized` = help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`) = note: required for `std::iter::Empty<()>` to implement `Iterator` = note: 171 redundant requirements hidden - = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>` to implement `Iterator` + = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>, ...>>` to implement `Iterator` = note: the full type name has been written to '$TEST_BUILD_DIR/traits/issue-91949-hangs-on-recursion/issue-91949-hangs-on-recursion.long-type-hash.txt' error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/type/type-check/assignment-in-if.stderr b/src/test/ui/type/type-check/assignment-in-if.stderr index 8ab08e25e30..9f4558adab1 100644 --- a/src/test/ui/type/type-check/assignment-in-if.stderr +++ b/src/test/ui/type/type-check/assignment-in-if.stderr @@ -68,7 +68,9 @@ error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:44:18 | LL | if x == x && x = x && x == x { - | ^ expected `bool`, found `usize` + | ------ ^ expected `bool`, found `usize` + | | + | expected because this is `bool` error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:44:22 @@ -91,7 +93,9 @@ error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:51:28 | LL | if x == x && x == x && x = x { - | ^ expected `bool`, found `usize` + | ---------------- ^ expected `bool`, found `usize` + | | + | expected because this is `bool` error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:51:8 diff --git a/src/test/ui/type/type-params-in-different-spaces-1.stderr b/src/test/ui/type/type-params-in-different-spaces-1.stderr index 4e73e10a301..7529f25bd8e 100644 --- a/src/test/ui/type/type-params-in-different-spaces-1.stderr +++ b/src/test/ui/type/type-params-in-different-spaces-1.stderr @@ -6,7 +6,9 @@ LL | trait BrokenAdd: Copy + Add<Output=Self> { LL | fn broken_add<T>(&self, rhs: T) -> Self { | - found type parameter LL | *self + rhs - | ^^^ expected type parameter `Self`, found type parameter `T` + | ----- ^^^ expected type parameter `Self`, found type parameter `T` + | | + | expected because this is `Self` | = note: expected type parameter `Self` found type parameter `T` diff --git a/src/test/ui/wrong-mul-method-signature.stderr b/src/test/ui/wrong-mul-method-signature.stderr index 9f8896f01ee..8338f61b22a 100644 --- a/src/test/ui/wrong-mul-method-signature.stderr +++ b/src/test/ui/wrong-mul-method-signature.stderr @@ -38,7 +38,9 @@ error[E0308]: mismatched types --> $DIR/wrong-mul-method-signature.rs:63:45 | LL | let x: Vec2 = Vec2 { x: 1.0, y: 2.0 } * 2.0; // trait had reversed order - | ^^^ expected struct `Vec2`, found floating-point number + | ----------------------- ^^^ expected struct `Vec2`, found floating-point number + | | + | expected because this is `Vec2` error[E0308]: mismatched types --> $DIR/wrong-mul-method-signature.rs:63:19 diff --git a/src/tools/cargo b/src/tools/cargo -Subproject f6e737b1e3386adb89333bf06a01f68a91ac530 +Subproject 70898e522116f6c23971e2a554b2dc85fd4c84c diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 17b0507682a..9263f051972 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -386,14 +386,12 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< Node::Expr(parent_expr) => { if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr) { - if Some(callee_def_id) == cx.tcx.lang_items().into_future_fn() { - return false; - } - let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder(); if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id) && let Some(param_ty) = fn_sig.inputs().get(arg_index) && let ty::Param(ParamTy { index: param_index , ..}) = param_ty.kind() + // https://github.com/rust-lang/rust-clippy/issues/9504 and https://github.com/rust-lang/rust-clippy/issues/10021 + && (*param_index as usize) < call_substs.len() { if fn_sig .inputs() diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 480e8e55cf3..e053a9dc888 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -303,7 +303,6 @@ fn check_terminator<'tcx>( TerminatorKind::SwitchInt { discr, - switch_ty: _, targets: _, } => check_operand(tcx, discr, span, body), diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 64d97e91442..c5767a79538 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -906,6 +906,7 @@ pub fn make_test_description<R: Read>( let has_asm_support = config.has_asm_support(); let has_asan = util::ASAN_SUPPORTED_TARGETS.contains(&&*config.target); let has_cfi = util::CFI_SUPPORTED_TARGETS.contains(&&*config.target); + let has_kcfi = util::KCFI_SUPPORTED_TARGETS.contains(&&*config.target); let has_lsan = util::LSAN_SUPPORTED_TARGETS.contains(&&*config.target); let has_msan = util::MSAN_SUPPORTED_TARGETS.contains(&&*config.target); let has_tsan = util::TSAN_SUPPORTED_TARGETS.contains(&&*config.target); @@ -957,6 +958,7 @@ pub fn make_test_description<R: Read>( && config.parse_name_directive(ln, "needs-sanitizer-support"); ignore |= !has_asan && config.parse_name_directive(ln, "needs-sanitizer-address"); ignore |= !has_cfi && config.parse_name_directive(ln, "needs-sanitizer-cfi"); + ignore |= !has_kcfi && config.parse_name_directive(ln, "needs-sanitizer-kcfi"); ignore |= !has_lsan && config.parse_name_directive(ln, "needs-sanitizer-leak"); ignore |= !has_msan && config.parse_name_directive(ln, "needs-sanitizer-memory"); ignore |= !has_tsan && config.parse_name_directive(ln, "needs-sanitizer-thread"); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index e07b71a7c47..1542b1c17ad 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3542,6 +3542,8 @@ impl<'test> TestCx<'test> { option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from), // Virtual `/rustc/$sha` coming from download-rustc: std::env::var_os("FAKE_DOWNLOAD_RUSTC_PREFIX").map(PathBuf::from), + // Tests using -Zsimulate-remapped-rust-src-base should use this fake path + Some("/rustc/FAKE_PREFIX".into()), ]; for base_dir in source_bases { if let Some(base_dir) = base_dir { diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index ec36f1e4fb7..ccba313ee35 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -42,6 +42,8 @@ pub const CFI_SUPPORTED_TARGETS: &[&str] = &[ "x86_64-unknown-netbsd", ]; +pub const KCFI_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-none", "x86_64-linux-none"]; + pub const LSAN_SUPPORTED_TARGETS: &[&str] = &[ // FIXME: currently broken, see #88132 // "aarch64-apple-darwin", diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index 10e6e252e94..f896a337f42 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -11,7 +11,6 @@ use rustc_target::abi::Size; use crate::*; pub mod stacked_borrows; -use stacked_borrows::diagnostics::RetagCause; pub type CallId = NonZeroU64; @@ -265,11 +264,19 @@ impl GlobalStateInner { impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { - fn retag(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> { + fn retag_ptr_value(&mut self, kind: RetagKind, val: &ImmTy<'tcx, Provenance>) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> { let this = self.eval_context_mut(); let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method; match method { - BorrowTrackerMethod::StackedBorrows => this.sb_retag(kind, place), + BorrowTrackerMethod::StackedBorrows => this.sb_retag_ptr_value(kind, val), + } + } + + fn retag_place_contents(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method; + match method { + BorrowTrackerMethod::StackedBorrows => this.sb_retag_place_contents(kind, place), } } diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs index 9a7b38b13a3..24b3489e0d1 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs @@ -459,10 +459,10 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { Operation::Dealloc(_) => format!(" due to deallocation"), Operation::Access(AccessOp { kind, tag, .. }) => format!(" due to {kind:?} access for {tag:?}"), - Operation::Retag(RetagOp { orig_tag, permission, .. }) => { + Operation::Retag(RetagOp { orig_tag, permission, new_tag, .. }) => { let permission = permission .expect("start_grant should set the current permission before popping a tag"); - format!(" due to {permission:?} retag from {orig_tag:?}") + format!(" due to {permission:?} retag from {orig_tag:?} (that retag created {new_tag:?})") } }; diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index bcac873251f..ffbc0086402 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -1,9 +1,13 @@ //! Implements "Stacked Borrows". See <https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md> //! for further information. +pub mod diagnostics; +mod item; +mod stack; + use log::trace; use std::cmp; -use std::fmt::{self, Write}; +use std::fmt::Write; use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::{Mutability, RetagKind}; @@ -15,15 +19,13 @@ use rustc_target::abi::{Abi, Size}; use crate::borrow_tracker::{ stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder, TagHistory}, - AccessKind, GlobalStateInner, ProtectorKind, RetagCause, RetagFields, + AccessKind, GlobalStateInner, ProtectorKind, RetagFields, }; use crate::*; -mod item; +use diagnostics::RetagCause; pub use item::{Item, Permission}; -mod stack; pub use stack::Stack; -pub mod diagnostics; pub type AllocState = Stacks; @@ -40,30 +42,104 @@ pub struct Stacks { modified_since_last_gc: bool, } -/// Indicates which kind of reference is being created. -/// Used by high-level `reborrow` to compute which permissions to grant to the -/// new pointer. -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -enum RefKind { - /// `Box`. - Box, - /// `&mut`. - Unique { two_phase: bool }, - /// `&` with or without interior mutability. - Shared, - /// `*mut`/`*const` (raw pointers). - Raw { mutable: bool }, +/// Indicates which permissions to grant to the retagged pointer. +#[derive(Clone, Debug)] +enum NewPermission { + Uniform { + perm: Permission, + access: Option<AccessKind>, + protector: Option<ProtectorKind>, + }, + FreezeSensitive { + freeze_perm: Permission, + freeze_access: Option<AccessKind>, + freeze_protector: Option<ProtectorKind>, + nonfreeze_perm: Permission, + nonfreeze_access: Option<AccessKind>, + // nonfreeze_protector must always be None + }, } -impl fmt::Display for RefKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl NewPermission { + /// A key function: determine the permissions to grant at a retag for the given kind of + /// reference/pointer. + fn from_ref_ty<'tcx>( + ty: ty::Ty<'tcx>, + kind: RetagKind, + cx: &crate::MiriInterpCx<'_, 'tcx>, + ) -> Self { + let protector = (kind == RetagKind::FnEntry).then_some(ProtectorKind::StrongProtector); + match ty.kind() { + ty::Ref(_, pointee, Mutability::Mut) => { + if kind == RetagKind::TwoPhase { + // We mostly just give up on 2phase-borrows, and treat these exactly like raw pointers. + assert!(protector.is_none()); // RetagKind can't be both FnEntry and TwoPhase. + NewPermission::Uniform { + perm: Permission::SharedReadWrite, + access: None, + protector: None, + } + } else if pointee.is_unpin(*cx.tcx, cx.param_env()) { + // A regular full mutable reference. + NewPermission::Uniform { + perm: Permission::Unique, + access: Some(AccessKind::Write), + protector, + } + } else { + NewPermission::Uniform { + perm: Permission::SharedReadWrite, + // FIXME: We emit `dereferenceable` for `!Unpin` mutable references, so we + // should do fake accesses here. But then we run into + // <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>, so for now + // we don't do that. + access: None, + protector, + } + } + } + ty::RawPtr(ty::TypeAndMut { mutbl: Mutability::Mut, .. }) => { + assert!(protector.is_none()); // RetagKind can't be both FnEntry and Raw. + // Mutable raw pointer. No access, not protected. + NewPermission::Uniform { + perm: Permission::SharedReadWrite, + access: None, + protector: None, + } + } + ty::Ref(_, _pointee, Mutability::Not) => { + NewPermission::FreezeSensitive { + freeze_perm: Permission::SharedReadOnly, + freeze_access: Some(AccessKind::Read), + freeze_protector: protector, + nonfreeze_perm: Permission::SharedReadWrite, + // Inside UnsafeCell, this does *not* count as an access, as there + // might actually be mutable references further up the stack that + // we have to keep alive. + nonfreeze_access: None, + // We do not protect inside UnsafeCell. + // This fixes https://github.com/rust-lang/rust/issues/55005. + } + } + ty::RawPtr(ty::TypeAndMut { mutbl: Mutability::Not, .. }) => { + assert!(protector.is_none()); // RetagKind can't be both FnEntry and Raw. + // `*const T`, when freshly created, are read-only in the frozen part. + NewPermission::FreezeSensitive { + freeze_perm: Permission::SharedReadOnly, + freeze_access: Some(AccessKind::Read), + freeze_protector: None, + nonfreeze_perm: Permission::SharedReadWrite, + nonfreeze_access: None, + } + } + _ => unreachable!(), + } + } + + fn protector(&self) -> Option<ProtectorKind> { match self { - RefKind::Box => write!(f, "Box"), - RefKind::Unique { two_phase: false } => write!(f, "unique reference"), - RefKind::Unique { two_phase: true } => write!(f, "unique reference (two-phase)"), - RefKind::Shared => write!(f, "shared reference"), - RefKind::Raw { mutable: true } => write!(f, "raw (mutable) pointer"), - RefKind::Raw { mutable: false } => write!(f, "raw (constant) pointer"), + NewPermission::Uniform { protector, .. } => *protector, + NewPermission::FreezeSensitive { freeze_protector, .. } => *freeze_protector, } } } @@ -518,10 +594,9 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' &mut self, place: &MPlaceTy<'tcx, Provenance>, size: Size, - kind: RefKind, - retag_cause: RetagCause, // What caused this retag, for diagnostics only + new_perm: NewPermission, new_tag: BorTag, - protect: Option<ProtectorKind>, + retag_cause: RetagCause, // What caused this retag, for diagnostics only ) -> InterpResult<'tcx, Option<AllocId>> { let this = self.eval_context_mut(); @@ -532,20 +607,16 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' let global = this.machine.borrow_tracker.as_ref().unwrap().borrow(); let ty = place.layout.ty; if global.tracked_pointer_tags.contains(&new_tag) { - let mut kind_str = format!("{kind}"); - match kind { - RefKind::Unique { two_phase: false } - if !ty.is_unpin(*this.tcx, this.param_env()) => - { - write!(kind_str, " (!Unpin pointee type {ty})").unwrap() - }, - RefKind::Shared - if !ty.is_freeze(*this.tcx, this.param_env()) => - { - write!(kind_str, " (!Freeze pointee type {ty})").unwrap() - }, - _ => write!(kind_str, " (pointee type {ty})").unwrap(), - }; + let mut kind_str = String::new(); + match new_perm { + NewPermission::Uniform { perm, .. } => + write!(kind_str, "{perm:?} permission").unwrap(), + NewPermission::FreezeSensitive { freeze_perm, .. } if ty.is_freeze(*this.tcx, this.param_env()) => + write!(kind_str, "{freeze_perm:?} permission").unwrap(), + NewPermission::FreezeSensitive { freeze_perm, nonfreeze_perm, .. } => + write!(kind_str, "{freeze_perm:?}/{nonfreeze_perm:?} permission for frozen/non-frozen parts").unwrap(), + } + write!(kind_str, " (pointee type {ty})").unwrap(); this.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag( new_tag.inner(), Some(kind_str), @@ -579,7 +650,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' ); let mut dcx = dcx.build(&mut stacked_borrows.history, base_offset); dcx.log_creation(); - if protect.is_some() { + if new_perm.protector().is_some() { dcx.log_protector(); } }, @@ -592,8 +663,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' if size == Size::ZERO { trace!( - "reborrow of size 0: {} reference {:?} derived from {:?} (pointee {})", - kind, + "reborrow of size 0: reference {:?} derived from {:?} (pointee {})", new_tag, place.ptr, place.layout.ty, @@ -630,8 +700,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' } trace!( - "reborrow: {} reference {:?} derived from {:?} (pointee {}): {:?}, size {}", - kind, + "reborrow: reference {:?} derived from {:?} (pointee {}): {:?}, size {}", new_tag, orig_tag, place.layout.ty, @@ -639,7 +708,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' size.bytes() ); - if let Some(protect) = protect { + if let Some(protect) = new_perm.protector() { // See comment in `Stack::item_invalidated` for why we store the tag twice. this.frame_mut().extra.borrow_tracker.as_mut().unwrap().protected_tags.push(new_tag); this.machine @@ -651,30 +720,45 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' .insert(new_tag, protect); } - // Update the stacks. - // Make sure that raw pointers and mutable shared references are reborrowed "weak": - // There could be existing unique pointers reborrowed from them that should remain valid! - let (perm, access) = match kind { - RefKind::Unique { two_phase } => { - // Permission is Unique only if the type is `Unpin` and this is not twophase - if !two_phase && place.layout.ty.is_unpin(*this.tcx, this.param_env()) { - (Permission::Unique, Some(AccessKind::Write)) - } else { - // FIXME: We emit `dereferenceable` for `!Unpin` mutable references, so we - // should do fake accesses here. But then we run into - // <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>, so for now - // we don't do that. - (Permission::SharedReadWrite, None) + // Update the stacks, according to the new permission information we are given. + match new_perm { + NewPermission::Uniform { perm, access, protector } => { + assert!(perm != Permission::SharedReadOnly); + // Here we can avoid `borrow()` calls because we have mutable references. + // Note that this asserts that the allocation is mutable -- but since we are creating a + // mutable pointer, that seems reasonable. + let (alloc_extra, machine) = this.get_alloc_extra_mut(alloc_id)?; + let stacked_borrows = alloc_extra.borrow_tracker_sb_mut().get_mut(); + let item = Item::new(new_tag, perm, protector.is_some()); + let range = alloc_range(base_offset, size); + let global = machine.borrow_tracker.as_ref().unwrap().borrow(); + let dcx = DiagnosticCxBuilder::retag( + machine, + retag_cause, + new_tag, + orig_tag, + alloc_range(base_offset, size), + ); + stacked_borrows.for_each(range, dcx, |stack, dcx, exposed_tags| { + stack.grant(orig_tag, item, access, &global, dcx, exposed_tags) + })?; + drop(global); + if let Some(access) = access { + assert_eq!(access, AccessKind::Write); + // Make sure the data race model also knows about this. + if let Some(data_race) = alloc_extra.data_race.as_mut() { + data_race.write(alloc_id, range, machine)?; + } } } - RefKind::Box => (Permission::Unique, Some(AccessKind::Write)), - RefKind::Raw { mutable: true } => { - // Creating a raw ptr does not count as an access - (Permission::SharedReadWrite, None) - } - RefKind::Shared | RefKind::Raw { mutable: false } => { - // Shared references and *const are a whole different kind of game, the - // permission is not uniform across the entire range! + NewPermission::FreezeSensitive { + freeze_perm, + freeze_access, + freeze_protector, + nonfreeze_perm, + nonfreeze_access, + } => { + // The permission is not uniform across the entire range! // We need a frozen-sensitive reborrow. // We have to use shared references to alloc/memory_extra here since // `visit_freeze_sensitive` needs to access the global state. @@ -684,22 +768,12 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' // Adjust range. range.start += base_offset; // We are only ever `SharedReadOnly` inside the frozen bits. - let (perm, access) = if frozen { - (Permission::SharedReadOnly, Some(AccessKind::Read)) - } else { - // Inside UnsafeCell, this does *not* count as an access, as there - // might actually be mutable references further up the stack that - // we have to keep alive. - (Permission::SharedReadWrite, None) - }; - let protected = if frozen { - protect.is_some() + let (perm, access, protector) = if frozen { + (freeze_perm, freeze_access, freeze_protector) } else { - // We do not protect inside UnsafeCell. - // This fixes https://github.com/rust-lang/rust/issues/55005. - false + (nonfreeze_perm, nonfreeze_access, None) }; - let item = Item::new(new_tag, perm, protected); + let item = Item::new(new_tag, perm, protector.is_some()); let global = this.machine.borrow_tracker.as_ref().unwrap().borrow(); let dcx = DiagnosticCxBuilder::retag( &this.machine, @@ -721,34 +795,6 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' } Ok(()) })?; - return Ok(Some(alloc_id)); - } - }; - - // Here we can avoid `borrow()` calls because we have mutable references. - // Note that this asserts that the allocation is mutable -- but since we are creating a - // mutable pointer, that seems reasonable. - let (alloc_extra, machine) = this.get_alloc_extra_mut(alloc_id)?; - let stacked_borrows = alloc_extra.borrow_tracker_sb_mut().get_mut(); - let item = Item::new(new_tag, perm, protect.is_some()); - let range = alloc_range(base_offset, size); - let global = machine.borrow_tracker.as_ref().unwrap().borrow(); - let dcx = DiagnosticCxBuilder::retag( - machine, - retag_cause, - new_tag, - orig_tag, - alloc_range(base_offset, size), - ); - stacked_borrows.for_each(range, dcx, |stack, dcx, exposed_tags| { - stack.grant(orig_tag, item, access, &global, dcx, exposed_tags) - })?; - drop(global); - if let Some(access) = access { - assert_eq!(access, AccessKind::Write); - // Make sure the data race model also knows about this. - if let Some(data_race) = alloc_extra.data_race.as_mut() { - data_race.write(alloc_id, range, machine)?; } } @@ -760,9 +806,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' fn sb_retag_reference( &mut self, val: &ImmTy<'tcx, Provenance>, - kind: RefKind, - retag_cause: RetagCause, // What caused this retag, for diagnostics only - protect: Option<ProtectorKind>, + new_perm: NewPermission, + cause: RetagCause, // What caused this retag, for diagnostics only ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> { let this = self.eval_context_mut(); // We want a place for where the ptr *points to*, so we get one. @@ -780,7 +825,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' let new_tag = this.machine.borrow_tracker.as_mut().unwrap().get_mut().new_ptr(); // Reborrow. - let alloc_id = this.sb_reborrow(&place, size, kind, retag_cause, new_tag, protect)?; + let alloc_id = this.sb_reborrow(&place, size, new_perm, new_tag, cause)?; // Adjust pointer. let new_place = place.map_provenance(|p| { @@ -807,7 +852,22 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { - fn sb_retag( + fn sb_retag_ptr_value( + &mut self, + kind: RetagKind, + val: &ImmTy<'tcx, Provenance>, + ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> { + let this = self.eval_context_mut(); + let new_perm = NewPermission::from_ref_ty(val.layout.ty, kind, this); + let retag_cause = match kind { + RetagKind::TwoPhase { .. } => RetagCause::TwoPhase, + RetagKind::FnEntry => unreachable!(), + RetagKind::Raw | RetagKind::Default => RetagCause::Normal, + }; + this.sb_retag_reference(&val, new_perm, retag_cause) + } + + fn sb_retag_place_contents( &mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>, @@ -815,9 +875,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let retag_fields = this.machine.borrow_tracker.as_mut().unwrap().get_mut().retag_fields; let retag_cause = match kind { - RetagKind::TwoPhase { .. } => RetagCause::TwoPhase, + RetagKind::Raw | RetagKind::TwoPhase { .. } => unreachable!(), // these can only happen in `retag_ptr_value` RetagKind::FnEntry => RetagCause::FnEntry, - RetagKind::Raw | RetagKind::Default => RetagCause::Normal, + RetagKind::Default => RetagCause::Normal, }; let mut visitor = RetagVisitor { ecx: this, kind, retag_cause, retag_fields }; return visitor.visit_value(place); @@ -831,15 +891,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } impl<'ecx, 'mir, 'tcx> RetagVisitor<'ecx, 'mir, 'tcx> { #[inline(always)] // yes this helps in our benchmarks - fn retag_place( + fn retag_ptr_inplace( &mut self, place: &PlaceTy<'tcx, Provenance>, - ref_kind: RefKind, + new_perm: NewPermission, retag_cause: RetagCause, - protector: Option<ProtectorKind>, ) -> InterpResult<'tcx> { let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?; - let val = self.ecx.sb_retag_reference(&val, ref_kind, retag_cause, protector)?; + let val = self.ecx.sb_retag_reference(&val, new_perm, retag_cause)?; self.ecx.write_immediate(*val, place)?; Ok(()) } @@ -856,13 +915,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn visit_box(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> { // Boxes get a weak protectors, since they may be deallocated. - self.retag_place( - place, - RefKind::Box, - self.retag_cause, - /*protector*/ - (self.kind == RetagKind::FnEntry).then_some(ProtectorKind::WeakProtector), - ) + let new_perm = NewPermission::Uniform { + perm: Permission::Unique, + access: Some(AccessKind::Write), + protector: (self.kind == RetagKind::FnEntry) + .then_some(ProtectorKind::WeakProtector), + }; + self.retag_ptr_inplace(place, new_perm, self.retag_cause) } fn visit_value(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> { @@ -876,36 +935,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Check the type of this value to see what to do with it (retag, or recurse). match place.layout.ty.kind() { - ty::Ref(_, _, mutbl) => { - let ref_kind = match mutbl { - Mutability::Mut => - RefKind::Unique { two_phase: self.kind == RetagKind::TwoPhase }, - Mutability::Not => RefKind::Shared, - }; - self.retag_place( - place, - ref_kind, - self.retag_cause, - /*protector*/ - (self.kind == RetagKind::FnEntry) - .then_some(ProtectorKind::StrongProtector), - )?; + ty::Ref(..) => { + let new_perm = + NewPermission::from_ref_ty(place.layout.ty, self.kind, self.ecx); + self.retag_ptr_inplace(place, new_perm, self.retag_cause)?; } - ty::RawPtr(tym) => { - // We definitely do *not* want to recurse into raw pointers -- wide raw - // pointers have fields, and for dyn Trait pointees those can have reference - // type! - if self.kind == RetagKind::Raw { - // Raw pointers need to be enabled. - self.retag_place( - place, - RefKind::Raw { mutable: tym.mutbl == Mutability::Mut }, - self.retag_cause, - /*protector*/ None, - )?; - } + ty::RawPtr(..) => { + // We do *not* want to recurse into raw pointers -- wide raw pointers have + // fields, and for dyn Trait pointees those can have reference type! } - _ if place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box()) => { + ty::Adt(adt, _) if adt.is_box() => { // Recurse for boxes, they require some tricky handling and will end up in `visit_box` above. // (Yes this means we technically also recursively retag the allocator itself // even if field retagging is not enabled. *shrug*) @@ -953,12 +992,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ptr_layout = this.layout_of(this.tcx.mk_mut_ptr(return_place.layout.ty))?; let val = ImmTy::from_immediate(return_place.to_ref(this), ptr_layout); // Reborrow it. With protection! That is part of the point. - let val = this.sb_retag_reference( - &val, - RefKind::Unique { two_phase: false }, - RetagCause::FnReturn, - /*protector*/ Some(ProtectorKind::StrongProtector), - )?; + let new_perm = NewPermission::Uniform { + perm: Permission::Unique, + access: Some(AccessKind::Write), + protector: Some(ProtectorKind::StrongProtector), + }; + let val = this.sb_retag_reference(&val, new_perm, RetagCause::FnReturn)?; // And use reborrowed pointer for return place. let return_place = this.ref_to_mplace(&val)?; this.frame_mut().return_place = return_place.into(); diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 074fa032dcc..c22ac50e455 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -63,9 +63,9 @@ impl MachineStopType for TerminationInfo {} /// Miri specific diagnostics pub enum NonHaltingDiagnostic { - /// (new_tag, new_kind, (alloc_id, base_offset, orig_tag)) + /// (new_tag, new_perm, (alloc_id, base_offset, orig_tag)) /// - /// new_kind is `None` for base tags. + /// new_perm is `None` for base tags. CreatedPointerTag(NonZeroU64, Option<String>, Option<(AllocId, AllocRange, ProvenanceExtra)>), /// This `Item` was popped from the borrow stack. The string explains the reason. PoppedPointerTag(Item, String), @@ -364,7 +364,9 @@ fn report_msg<'tcx>( if is_local && idx > 0 { err.span_note(frame_info.span, &frame_info.to_string()); } else { - err.note(&frame_info.to_string()); + let sm = sess.source_map(); + let span = sm.span_to_embeddable_string(frame_info.span); + err.note(format!("{frame_info} at {span}")); } } @@ -393,10 +395,10 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { let msg = match &e { CreatedPointerTag(tag, None, _) => format!("created base tag {tag:?}"), - CreatedPointerTag(tag, Some(kind), None) => format!("created {tag:?} for {kind}"), - CreatedPointerTag(tag, Some(kind), Some((alloc_id, range, orig_tag))) => + CreatedPointerTag(tag, Some(perm), None) => format!("created {tag:?} with {perm} derived from unknown tag"), + CreatedPointerTag(tag, Some(perm), Some((alloc_id, range, orig_tag))) => format!( - "created tag {tag:?} for {kind} at {alloc_id:?}{range:?} derived from {orig_tag:?}" + "created tag {tag:?} with {perm} at {alloc_id:?}{range:?} derived from {orig_tag:?}" ), PoppedPointerTag(item, cause) => format!("popped tracked tag for item {item:?}{cause}"), CreatedCallId(id) => format!("function call with id {id}"), diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index c110229c985..e5b1eb2e487 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -967,8 +967,9 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { ptr: Pointer<Self::Provenance>, ) -> InterpResult<'tcx> { match ptr.provenance { - Provenance::Concrete { alloc_id, tag } => - intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag), + Provenance::Concrete { alloc_id, tag } => { + intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag) + } Provenance::Wildcard => { // No need to do anything for wildcard pointers as // their provenances have already been previously exposed. @@ -1055,13 +1056,26 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } #[inline(always)] - fn retag( + fn retag_ptr_value( + ecx: &mut InterpCx<'mir, 'tcx, Self>, + kind: mir::RetagKind, + val: &ImmTy<'tcx, Provenance>, + ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> { + if ecx.machine.borrow_tracker.is_some() { + ecx.retag_ptr_value(kind, val) + } else { + Ok(val.clone()) + } + } + + #[inline(always)] + fn retag_place_contents( ecx: &mut InterpCx<'mir, 'tcx, Self>, kind: mir::RetagKind, place: &PlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { if ecx.machine.borrow_tracker.is_some() { - ecx.retag(kind, place)?; + ecx.retag_place_contents(kind, place)?; } Ok(()) } diff --git a/src/tools/miri/tests/fail/abort-terminator.stderr b/src/tools/miri/tests/fail/abort-terminator.stderr index ec9ce76685b..2d3275f6b19 100644 --- a/src/tools/miri/tests/fail/abort-terminator.stderr +++ b/src/tools/miri/tests/fail/abort-terminator.stderr @@ -10,7 +10,7 @@ LL | | } | |_^ the program aborted execution | = note: inside `panic_abort` at $DIR/abort-terminator.rs:LL:CC -note: inside `main` at $DIR/abort-terminator.rs:LL:CC +note: inside `main` --> $DIR/abort-terminator.rs:LL:CC | LL | panic_abort(); diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr index 28439b54b29..095eeeb79de 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr @@ -8,7 +8,7 @@ LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC -note: inside `main` at $DIR/deallocate-bad-alignment.rs:LL:CC +note: inside `main` --> $DIR/deallocate-bad-alignment.rs:LL:CC | LL | dealloc(x, Layout::from_size_align_unchecked(1, 2)); diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr index a6ceab1f56f..5fe93c841b2 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr +++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr @@ -8,7 +8,7 @@ LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC -note: inside `main` at $DIR/deallocate-bad-size.rs:LL:CC +note: inside `main` --> $DIR/deallocate-bad-size.rs:LL:CC | LL | dealloc(x, Layout::from_size_align_unchecked(2, 1)); diff --git a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr index b6c5b6f97ee..fa7a74ee13c 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr +++ b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr @@ -8,7 +8,7 @@ LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC -note: inside `main` at $DIR/deallocate-twice.rs:LL:CC +note: inside `main` --> $DIR/deallocate-twice.rs:LL:CC | LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr index 4ee85add6c2..62ffb8142a3 100644 --- a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr +++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr @@ -9,7 +9,7 @@ LL | FREE(); = note: BACKTRACE: = note: inside `std::sys::PLATFORM::alloc::<impl std::alloc::GlobalAlloc for std::alloc::System>::dealloc` at RUSTLIB/std/src/sys/PLATFORM/alloc.rs:LL:CC = note: inside `<std::alloc::System as std::alloc::Allocator>::deallocate` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` at $DIR/global_system_mixup.rs:LL:CC +note: inside `main` --> $DIR/global_system_mixup.rs:LL:CC | LL | System.deallocate(ptr, l); diff --git a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr index c11b5a85104..24cabb39564 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr @@ -8,7 +8,7 @@ LL | unsafe { __rust_realloc(ptr, layout.size(), layout.align(), new_size) } = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `std::alloc::realloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC -note: inside `main` at $DIR/reallocate-bad-size.rs:LL:CC +note: inside `main` --> $DIR/reallocate-bad-size.rs:LL:CC | LL | let _y = realloc(x, Layout::from_size_align_unchecked(2, 1), 1); diff --git a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr index c7db5a72904..b1460bfb763 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr @@ -8,7 +8,7 @@ LL | unsafe { __rust_realloc(ptr, layout.size(), layout.align(), new_size) } = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `std::alloc::realloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC -note: inside `main` at $DIR/reallocate-dangling.rs:LL:CC +note: inside `main` --> $DIR/reallocate-dangling.rs:LL:CC | LL | let _z = realloc(x, Layout::from_size_align_unchecked(1, 1), 1); diff --git a/src/tools/miri/tests/fail/alloc/stack_free.stderr b/src/tools/miri/tests/fail/alloc/stack_free.stderr index 44991542b13..b1636050a78 100644 --- a/src/tools/miri/tests/fail/alloc/stack_free.stderr +++ b/src/tools/miri/tests/fail/alloc/stack_free.stderr @@ -12,7 +12,7 @@ LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } = note: inside `alloc::alloc::box_free::<i32, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `std::ptr::drop_in_place::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::<std::boxed::Box<i32>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside `main` at $DIR/stack_free.rs:LL:CC +note: inside `main` --> $DIR/stack_free.rs:LL:CC | LL | drop(bad_box); diff --git a/src/tools/miri/tests/fail/box-cell-alias.stderr b/src/tools/miri/tests/fail/box-cell-alias.stderr index 83701639976..f57b52c4bda 100644 --- a/src/tools/miri/tests/fail/box-cell-alias.stderr +++ b/src/tools/miri/tests/fail/box-cell-alias.stderr @@ -21,7 +21,7 @@ LL | let res = helper(val, ptr); | ^^^ = note: BACKTRACE: = note: inside `helper` at $DIR/box-cell-alias.rs:LL:CC -note: inside `main` at $DIR/box-cell-alias.rs:LL:CC +note: inside `main` --> $DIR/box-cell-alias.rs:LL:CC | LL | let res = helper(val, ptr); diff --git a/src/tools/miri/tests/fail/concurrency/windows_join_detached.stderr b/src/tools/miri/tests/fail/concurrency/windows_join_detached.stderr index 20f34cf104d..7b297b260d8 100644 --- a/src/tools/miri/tests/fail/concurrency/windows_join_detached.stderr +++ b/src/tools/miri/tests/fail/concurrency/windows_join_detached.stderr @@ -10,7 +10,7 @@ LL | let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle( = note: inside `std::sys::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/PLATFORM/thread.rs:LL:CC = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC -note: inside `main` at $DIR/windows_join_detached.rs:LL:CC +note: inside `main` --> $DIR/windows_join_detached.rs:LL:CC | LL | thread.join().unwrap(); diff --git a/src/tools/miri/tests/fail/crates/tokio_mvp.stderr b/src/tools/miri/tests/fail/crates/tokio_mvp.stderr index 5a80d1ac5a9..1e7dfaa7499 100644 --- a/src/tools/miri/tests/fail/crates/tokio_mvp.stderr +++ b/src/tools/miri/tests/fail/crates/tokio_mvp.stderr @@ -6,7 +6,7 @@ LL | let res = syscall!(epoll_create1(libc::EPOLL_CLOEXEC)); | = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support = note: BACKTRACE: -note: inside `main` at $DIR/tokio_mvp.rs:LL:CC +note: inside `main` --> $DIR/tokio_mvp.rs:LL:CC | LL | #[tokio::main] diff --git a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr index 72e5f20f924..2ba8116cadc 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr @@ -8,7 +8,7 @@ LL | unsafe { &mut *(LEAK as *mut i32) }; = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `evil` at $DIR/storage_dead_dangling.rs:LL:CC -note: inside `main` at $DIR/storage_dead_dangling.rs:LL:CC +note: inside `main` --> $DIR/storage_dead_dangling.rs:LL:CC | LL | evil(); diff --git a/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr b/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr index 5de27108ab6..0075f877b29 100644 --- a/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr +++ b/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr @@ -8,7 +8,7 @@ LL | } = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `race` at $DIR/stack_pop_race.rs:LL:CC -note: inside `main` at $DIR/stack_pop_race.rs:LL:CC +note: inside `main` --> $DIR/stack_pop_race.rs:LL:CC | LL | race(0); diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr index 7d9302e3e3a..484f703f9c1 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr @@ -11,7 +11,7 @@ LL | | } | |_^ the program aborted execution | = note: inside `nounwind` at $DIR/exported_symbol_bad_unwind2.rs:LL:CC -note: inside `main` at $DIR/exported_symbol_bad_unwind2.rs:LL:CC +note: inside `main` --> $DIR/exported_symbol_bad_unwind2.rs:LL:CC | LL | unsafe { nounwind() } diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr index 7d9302e3e3a..484f703f9c1 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr @@ -11,7 +11,7 @@ LL | | } | |_^ the program aborted execution | = note: inside `nounwind` at $DIR/exported_symbol_bad_unwind2.rs:LL:CC -note: inside `main` at $DIR/exported_symbol_bad_unwind2.rs:LL:CC +note: inside `main` --> $DIR/exported_symbol_bad_unwind2.rs:LL:CC | LL | unsafe { nounwind() } diff --git a/src/tools/miri/tests/fail/generator-pinned-moved.stderr b/src/tools/miri/tests/fail/generator-pinned-moved.stderr index 4f73671a789..80c5794736a 100644 --- a/src/tools/miri/tests/fail/generator-pinned-moved.stderr +++ b/src/tools/miri/tests/fail/generator-pinned-moved.stderr @@ -8,13 +8,13 @@ LL | *num += 1; = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside closure at $DIR/generator-pinned-moved.rs:LL:CC -note: inside `<GeneratorIteratorAdapter<[static generator@$DIR/generator-pinned-moved.rs:LL:CC]> as std::iter::Iterator>::next` at $DIR/generator-pinned-moved.rs:LL:CC +note: inside `<GeneratorIteratorAdapter<[static generator@$DIR/generator-pinned-moved.rs:LL:CC]> as std::iter::Iterator>::next` --> $DIR/generator-pinned-moved.rs:LL:CC | LL | match me.resume(()) { | ^^^^^^^^^^^^^ = note: inside `<std::boxed::Box<GeneratorIteratorAdapter<[static generator@$DIR/generator-pinned-moved.rs:LL:CC]>> as std::iter::Iterator>::next` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `main` at $DIR/generator-pinned-moved.rs:LL:CC +note: inside `main` --> $DIR/generator-pinned-moved.rs:LL:CC | LL | generator_iterator_2.next(); // and use moved value diff --git a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr index 36bb9643b48..5c73c76a161 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr @@ -8,7 +8,7 @@ LL | unsafe { intrinsics::simd_cast(self) } = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `std::simd::Simd::<f32, 2>::to_int_unchecked::<i32>` at RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC -note: inside `main` at $DIR/simd-float-to-int.rs:LL:CC +note: inside `main` --> $DIR/simd-float-to-int.rs:LL:CC | LL | let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked(); diff --git a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr index 29a4ef65705..7512d57f672 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr @@ -8,7 +8,7 @@ LL | unsafe { intrinsics::simd_gather(or, ptrs, enable.to_int()) } = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `std::simd::Simd::<i8, 4>::gather_select_unchecked` at RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC -note: inside `main` at $DIR/simd-gather.rs:LL:CC +note: inside `main` --> $DIR/simd-gather.rs:LL:CC | LL | let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0)); diff --git a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr index fde85a63503..a9ad60a0e5b 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr @@ -8,7 +8,7 @@ LL | intrinsics::simd_scatter(self, ptrs, enable.to_int()) = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `std::simd::Simd::<i8, 4>::scatter_select_unchecked` at RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC -note: inside `main` at $DIR/simd-scatter.rs:LL:CC +note: inside `main` --> $DIR/simd-scatter.rs:LL:CC | LL | / Simd::from_array([-27, 82, -41, 124]).scatter_select_unchecked( diff --git a/src/tools/miri/tests/fail/issue-miri-1112.stderr b/src/tools/miri/tests/fail/issue-miri-1112.stderr index e6644a72849..f1cb50ab9be 100644 --- a/src/tools/miri/tests/fail/issue-miri-1112.stderr +++ b/src/tools/miri/tests/fail/issue-miri-1112.stderr @@ -8,7 +8,7 @@ LL | let obj = std::mem::transmute::<FatPointer, *mut FunnyPointer>(obj) = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `FunnyPointer::from_data_ptr` at $DIR/issue-miri-1112.rs:LL:CC -note: inside `main` at $DIR/issue-miri-1112.rs:LL:CC +note: inside `main` --> $DIR/issue-miri-1112.rs:LL:CC | LL | let _raw: &FunnyPointer = FunnyPointer::from_data_ptr(&hello, &meta as *const _); diff --git a/src/tools/miri/tests/fail/never_transmute_void.stderr b/src/tools/miri/tests/fail/never_transmute_void.stderr index 4c3a3d075f0..413172b2546 100644 --- a/src/tools/miri/tests/fail/never_transmute_void.stderr +++ b/src/tools/miri/tests/fail/never_transmute_void.stderr @@ -8,7 +8,7 @@ LL | match v.0 {} = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `m::f` at $DIR/never_transmute_void.rs:LL:CC -note: inside `main` at $DIR/never_transmute_void.rs:LL:CC +note: inside `main` --> $DIR/never_transmute_void.rs:LL:CC | LL | m::f(v); diff --git a/src/tools/miri/tests/fail/panic/bad_unwind.stderr b/src/tools/miri/tests/fail/panic/bad_unwind.stderr index 23c33f5e7f3..5d7f01f4786 100644 --- a/src/tools/miri/tests/fail/panic/bad_unwind.stderr +++ b/src/tools/miri/tests/fail/panic/bad_unwind.stderr @@ -13,7 +13,7 @@ LL | std::panic::catch_unwind(|| unwind()).unwrap_err(); = note: inside `std::panicking::r#try::do_call::<[closure@$DIR/bad_unwind.rs:LL:CC], ()>` at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside `std::panicking::r#try::<(), [closure@$DIR/bad_unwind.rs:LL:CC]>` at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside `std::panic::catch_unwind::<[closure@$DIR/bad_unwind.rs:LL:CC], ()>` at RUSTLIB/std/src/panic.rs:LL:CC -note: inside `main` at $DIR/bad_unwind.rs:LL:CC +note: inside `main` --> $DIR/bad_unwind.rs:LL:CC | LL | std::panic::catch_unwind(|| unwind()).unwrap_err(); diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr index f1d2b4de97c..6bf13f21601 100644 --- a/src/tools/miri/tests/fail/panic/double_panic.stderr +++ b/src/tools/miri/tests/fail/panic/double_panic.stderr @@ -75,13 +75,13 @@ LL | ABORT(); = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::rt::begin_panic<&str>::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC -note: inside `<Foo as std::ops::Drop>::drop` at RUSTLIB/std/src/panic.rs:LL:CC +note: inside `<Foo as std::ops::Drop>::drop` --> $DIR/double_panic.rs:LL:CC | LL | panic!("second"); | ^ = note: inside `std::ptr::drop_in_place::<Foo> - shim(Some(Foo))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC -note: inside `main` at $DIR/double_panic.rs:LL:CC +note: inside `main` --> $DIR/double_panic.rs:LL:CC | LL | } diff --git a/src/tools/miri/tests/fail/panic/no_std.stderr b/src/tools/miri/tests/fail/panic/no_std.stderr index 568b286e1d3..39ad0d268b9 100644 --- a/src/tools/miri/tests/fail/panic/no_std.stderr +++ b/src/tools/miri/tests/fail/panic/no_std.stderr @@ -6,7 +6,7 @@ LL | core::intrinsics::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ the program aborted execution | = note: inside `panic_handler` at $DIR/no_std.rs:LL:CC -note: inside `start` at RUSTLIB/core/src/panic.rs:LL:CC +note: inside `start` --> $DIR/no_std.rs:LL:CC | LL | panic!("blarg I am dead") diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.stderr b/src/tools/miri/tests/fail/panic/panic_abort1.stderr index 75471994546..d25dd7be635 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort1.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort1.stderr @@ -12,7 +12,7 @@ LL | ABORT(); = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::rt::begin_panic<&str>::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC -note: inside `main` at RUSTLIB/std/src/panic.rs:LL:CC +note: inside `main` --> $DIR/panic_abort1.rs:LL:CC | LL | std::panic!("panicking from libstd"); diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.stderr b/src/tools/miri/tests/fail/panic/panic_abort2.stderr index 2fdf889d798..f56d509a697 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort2.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort2.stderr @@ -13,7 +13,7 @@ LL | ABORT(); = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC -note: inside `main` at RUSTLIB/std/src/panic.rs:LL:CC +note: inside `main` --> $DIR/panic_abort2.rs:LL:CC | LL | std::panic!("{}-panicking from libstd", 42); diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.stderr b/src/tools/miri/tests/fail/panic/panic_abort3.stderr index 8704b0d940b..43792f76993 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort3.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort3.stderr @@ -13,7 +13,7 @@ LL | ABORT(); = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC -note: inside `main` at RUSTLIB/core/src/panic.rs:LL:CC +note: inside `main` --> $DIR/panic_abort3.rs:LL:CC | LL | core::panic!("panicking from libcore"); diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.stderr b/src/tools/miri/tests/fail/panic/panic_abort4.stderr index 1d75d72c031..89e181bfb27 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort4.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort4.stderr @@ -13,7 +13,7 @@ LL | ABORT(); = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC -note: inside `main` at RUSTLIB/core/src/panic.rs:LL:CC +note: inside `main` --> $DIR/panic_abort4.rs:LL:CC | LL | core::panic!("{}-panicking from libcore", 42); diff --git a/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr b/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr index f7c5f6046e1..042d8cd4afe 100644 --- a/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr +++ b/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr @@ -8,7 +8,7 @@ LL | let _val = *left_ptr; = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `deref` at $DIR/provenance_transmute.rs:LL:CC -note: inside `main` at $DIR/provenance_transmute.rs:LL:CC +note: inside `main` --> $DIR/provenance_transmute.rs:LL:CC | LL | deref(ptr1, ptr2.with_addr(ptr1.addr())); diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr index 269b1383aad..2385439c8a5 100644 --- a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr +++ b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr @@ -17,7 +17,7 @@ LL | let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode a = note: inside `std::fs::OpenOptions::_open` at RUSTLIB/std/src/fs.rs:LL:CC = note: inside `std::fs::OpenOptions::open::<&std::path::Path>` at RUSTLIB/std/src/fs.rs:LL:CC = note: inside `std::fs::File::open::<&str>` at RUSTLIB/std/src/fs.rs:LL:CC -note: inside `main` at $DIR/isolated_file.rs:LL:CC +note: inside `main` --> $DIR/isolated_file.rs:LL:CC | LL | let _file = std::fs::File::open("file.txt").unwrap(); diff --git a/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.stderr b/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.stderr index 414ac1cb1b7..35ff1926b06 100644 --- a/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.stderr +++ b/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.stderr @@ -8,7 +8,7 @@ LL | let _fd = unsafe { libc::mkstemp(s) }; = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `test_mkstemp_immutable_arg` at $DIR/mkstemp_immutable_arg.rs:LL:CC -note: inside `main` at $DIR/mkstemp_immutable_arg.rs:LL:CC +note: inside `main` --> $DIR/mkstemp_immutable_arg.rs:LL:CC | LL | test_mkstemp_immutable_arg(); diff --git a/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.stderr b/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.stderr index 38d033b4945..5a8e7352c76 100644 --- a/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.stderr +++ b/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.stderr @@ -8,7 +8,7 @@ LL | ...safe { libc::open(name_ptr, libc::O_CREAT) }; = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `test_file_open_missing_needed_mode` at $DIR/unix_open_missing_required_mode.rs:LL:CC -note: inside `main` at $DIR/unix_open_missing_required_mode.rs:LL:CC +note: inside `main` --> $DIR/unix_open_missing_required_mode.rs:LL:CC | LL | test_file_open_missing_needed_mode(); diff --git a/src/tools/miri/tests/fail/should-pass/cpp20_rwc_syncs.stderr b/src/tools/miri/tests/fail/should-pass/cpp20_rwc_syncs.stderr index 8a24b085a99..325565fa1e7 100644 --- a/src/tools/miri/tests/fail/should-pass/cpp20_rwc_syncs.stderr +++ b/src/tools/miri/tests/fail/should-pass/cpp20_rwc_syncs.stderr @@ -8,7 +8,7 @@ LL | std::hint::unreachable_unchecked(); = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `test_cpp20_rwc_syncs` at $DIR/cpp20_rwc_syncs.rs:LL:CC -note: inside `main` at $DIR/cpp20_rwc_syncs.rs:LL:CC +note: inside `main` --> $DIR/cpp20_rwc_syncs.rs:LL:CC | LL | test_cpp20_rwc_syncs(); diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.stderr b/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.stderr index 268d253ad5b..4514abb4ab2 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut1.stderr @@ -18,7 +18,7 @@ LL | pub fn safe(_x: &mut i32, _y: &mut i32) {} | ^^ = note: BACKTRACE: = note: inside `safe` at $DIR/aliasing_mut1.rs:LL:CC -note: inside `main` at $DIR/aliasing_mut1.rs:LL:CC +note: inside `main` --> $DIR/aliasing_mut1.rs:LL:CC | LL | safe_raw(xraw, xraw); diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.stderr b/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.stderr index 77a542f45a2..9ca9743cbd9 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut2.stderr @@ -18,7 +18,7 @@ LL | pub fn safe(_x: &i32, _y: &mut i32) {} | ^^ = note: BACKTRACE: = note: inside `safe` at $DIR/aliasing_mut2.rs:LL:CC -note: inside `main` at $DIR/aliasing_mut2.rs:LL:CC +note: inside `main` --> $DIR/aliasing_mut2.rs:LL:CC | LL | safe_raw(xshr, xraw); diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.stderr b/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.stderr index eb6b01fc6b1..b504097a3c9 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut3.stderr @@ -21,7 +21,7 @@ LL | safe_raw(xraw, xshr); | ^^^^^^^^^^^^^^^^^^^^ = note: BACKTRACE: = note: inside `safe` at $DIR/aliasing_mut3.rs:LL:CC -note: inside `main` at $DIR/aliasing_mut3.rs:LL:CC +note: inside `main` --> $DIR/aliasing_mut3.rs:LL:CC | LL | safe_raw(xraw, xshr); diff --git a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.stderr b/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.stderr index e592b154a73..6fe0d709029 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/aliasing_mut4.stderr @@ -18,7 +18,7 @@ LL | pub fn safe(_x: &i32, _y: &mut Cell<i32>) {} | ^^ = note: BACKTRACE: = note: inside `safe` at $DIR/aliasing_mut4.rs:LL:CC -note: inside `main` at $DIR/aliasing_mut4.rs:LL:CC +note: inside `main` --> $DIR/aliasing_mut4.rs:LL:CC | LL | safe_raw(xshr, xraw as *mut _); diff --git a/src/tools/miri/tests/fail/stacked_borrows/box_exclusive_violation1.stderr b/src/tools/miri/tests/fail/stacked_borrows/box_exclusive_violation1.stderr index d82b8342f12..f114130f6fa 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/box_exclusive_violation1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/box_exclusive_violation1.stderr @@ -21,12 +21,12 @@ LL | *our = 5; | ^^^^^^^^ = note: BACKTRACE: = note: inside `unknown_code_2` at $DIR/box_exclusive_violation1.rs:LL:CC -note: inside `demo_box_advanced_unique` at $DIR/box_exclusive_violation1.rs:LL:CC +note: inside `demo_box_advanced_unique` --> $DIR/box_exclusive_violation1.rs:LL:CC | LL | unknown_code_2(); | ^^^^^^^^^^^^^^^^ -note: inside `main` at $DIR/box_exclusive_violation1.rs:LL:CC +note: inside `main` --> $DIR/box_exclusive_violation1.rs:LL:CC | LL | demo_box_advanced_unique(Box::new(0)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/box_noalias_violation.stderr b/src/tools/miri/tests/fail/stacked_borrows/box_noalias_violation.stderr index 3c84cbcfd51..139fcd0ca45 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/box_noalias_violation.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/box_noalias_violation.stderr @@ -18,7 +18,7 @@ LL | unsafe fn test(mut x: Box<i32>, y: *const i32) -> i32 { | ^^^^^ = note: BACKTRACE: = note: inside `test` at $DIR/box_noalias_violation.rs:LL:CC -note: inside `main` at $DIR/box_noalias_violation.rs:LL:CC +note: inside `main` --> $DIR/box_noalias_violation.rs:LL:CC | LL | test(Box::from_raw(ptr), ptr); diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr index bb3eaec1e85..516964b9a4e 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr @@ -12,18 +12,18 @@ LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } = note: inside `alloc::alloc::box_free::<i32, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `std::ptr::drop_in_place::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::<std::boxed::Box<i32>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure at $DIR/deallocate_against_protector1.rs:LL:CC +note: inside closure --> $DIR/deallocate_against_protector1.rs:LL:CC | LL | drop(unsafe { Box::from_raw(raw) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: inside `<[closure@$DIR/deallocate_against_protector1.rs:LL:CC] as std::ops::FnOnce<(&mut i32,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC -note: inside `inner` at $DIR/deallocate_against_protector1.rs:LL:CC +note: inside `inner` --> $DIR/deallocate_against_protector1.rs:LL:CC | LL | f(x) | ^^^^ -note: inside `main` at $DIR/deallocate_against_protector1.rs:LL:CC +note: inside `main` --> $DIR/deallocate_against_protector1.rs:LL:CC | LL | / inner(Box::leak(Box::new(0)), |x| { diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.stderr b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.stderr index 25bab1aa564..47cfa0de725 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector2.stderr @@ -12,18 +12,18 @@ LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) } = note: inside `alloc::alloc::box_free::<NotUnpin, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `std::ptr::drop_in_place::<std::boxed::Box<NotUnpin>> - shim(Some(std::boxed::Box<NotUnpin>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::<std::boxed::Box<NotUnpin>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure at $DIR/deallocate_against_protector2.rs:LL:CC +note: inside closure --> $DIR/deallocate_against_protector2.rs:LL:CC | LL | drop(unsafe { Box::from_raw(raw) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: inside `<[closure@$DIR/deallocate_against_protector2.rs:LL:CC] as std::ops::FnOnce<(&mut NotUnpin,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC -note: inside `inner` at $DIR/deallocate_against_protector2.rs:LL:CC +note: inside `inner` --> $DIR/deallocate_against_protector2.rs:LL:CC | LL | f(x) | ^^^^ -note: inside `main` at $DIR/deallocate_against_protector2.rs:LL:CC +note: inside `main` --> $DIR/deallocate_against_protector2.rs:LL:CC | LL | / inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| { diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr index 3b7802901a5..f2f13d0d559 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr @@ -18,7 +18,7 @@ LL | ptr1.write(0); | ^^^^^^^^^^^^^ = note: BACKTRACE: = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC -note: inside `main` at $DIR/illegal_deALLOC.rs:LL:CC +note: inside `main` --> $DIR/illegal_deALLOC.rs:LL:CC | LL | dealloc(ptr2, Layout::from_size_align_unchecked(1, 1)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write6.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_write6.stderr index 1a627b8a883..49d9050f309 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write6.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write6.stderr @@ -18,7 +18,7 @@ LL | fn foo(a: &mut u32, y: *mut u32) -> u32 { | ^ = note: BACKTRACE: = note: inside `foo` at $DIR/illegal_write6.rs:LL:CC -note: inside `main` at $DIR/illegal_write6.rs:LL:CC +note: inside `main` --> $DIR/illegal_write6.rs:LL:CC | LL | foo(x, p); diff --git a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr index 1ef36b7ac10..a53c633c381 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr @@ -18,7 +18,7 @@ LL | fn inner(x: *mut i32, _y: &mut i32) { | ^^ = note: BACKTRACE: = note: inside `inner` at $DIR/invalidate_against_protector1.rs:LL:CC -note: inside `main` at $DIR/invalidate_against_protector1.rs:LL:CC +note: inside `main` --> $DIR/invalidate_against_protector1.rs:LL:CC | LL | inner(xraw, xref); diff --git a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector2.stderr b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector2.stderr index 941b936e5d7..6ee78d1aac6 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector2.stderr @@ -18,7 +18,7 @@ LL | fn inner(x: *mut i32, _y: &i32) { | ^^ = note: BACKTRACE: = note: inside `inner` at $DIR/invalidate_against_protector2.rs:LL:CC -note: inside `main` at $DIR/invalidate_against_protector2.rs:LL:CC +note: inside `main` --> $DIR/invalidate_against_protector2.rs:LL:CC | LL | inner(xraw, xref); diff --git a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector3.stderr b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector3.stderr index 176a859ee8a..2b38dea9dbb 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector3.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector3.stderr @@ -18,7 +18,7 @@ LL | fn inner(x: *mut i32, _y: &i32) { | ^^ = note: BACKTRACE: = note: inside `inner` at $DIR/invalidate_against_protector3.rs:LL:CC -note: inside `main` at $DIR/invalidate_against_protector3.rs:LL:CC +note: inside `main` --> $DIR/invalidate_against_protector3.rs:LL:CC | LL | inner(ptr, &*ptr); diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.stderr b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.stderr index 16c8810a8e6..c69a3af293c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.stderr @@ -9,7 +9,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) = note: BACKTRACE: = note: inside `std::boxed::Box::<u32>::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::boxed::Box::<u32>::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `main` at $DIR/issue-miri-1050-1.rs:LL:CC +note: inside `main` --> $DIR/issue-miri-1050-1.rs:LL:CC | LL | drop(Box::from_raw(ptr as *mut u32)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.stderr b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.stderr index d57e7662e50..23d7fdcd03b 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.stderr @@ -9,7 +9,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) = note: BACKTRACE: = note: inside `std::boxed::Box::<i32>::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::boxed::Box::<i32>::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `main` at $DIR/issue-miri-1050-2.rs:LL:CC +note: inside `main` --> $DIR/issue-miri-1050-2.rs:LL:CC | LL | drop(Box::from_raw(ptr.as_ptr())); diff --git a/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr b/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr index 1c7f8e12d3d..2f3900c40d7 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr @@ -21,12 +21,12 @@ LL | *our = 5; | ^^^^^^^^ = note: BACKTRACE: = note: inside `unknown_code_2` at $DIR/mut_exclusive_violation1.rs:LL:CC -note: inside `demo_mut_advanced_unique` at $DIR/mut_exclusive_violation1.rs:LL:CC +note: inside `demo_mut_advanced_unique` --> $DIR/mut_exclusive_violation1.rs:LL:CC | LL | unknown_code_2(); | ^^^^^^^^^^^^^^^^ -note: inside `main` at $DIR/mut_exclusive_violation1.rs:LL:CC +note: inside `main` --> $DIR/mut_exclusive_violation1.rs:LL:CC | LL | demo_mut_advanced_unique(&mut 0); diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.stderr b/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.stderr index 70186dd3a53..90677dfaf55 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.stderr @@ -19,17 +19,17 @@ LL | fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { = note: BACKTRACE: = note: inside `std::boxed::Box::<i32>::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::boxed::Box::<i32>::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside closure at $DIR/newtype_pair_retagging.rs:LL:CC +note: inside closure --> $DIR/newtype_pair_retagging.rs:LL:CC | LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ -note: inside `dealloc_while_running::<[closure@$DIR/newtype_pair_retagging.rs:LL:CC]>` at $DIR/newtype_pair_retagging.rs:LL:CC +note: inside `dealloc_while_running::<[closure@$DIR/newtype_pair_retagging.rs:LL:CC]>` --> $DIR/newtype_pair_retagging.rs:LL:CC | LL | dealloc(); | ^^^^^^^^^ -note: inside `main` at $DIR/newtype_pair_retagging.rs:LL:CC +note: inside `main` --> $DIR/newtype_pair_retagging.rs:LL:CC | LL | / dealloc_while_running( diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.stderr b/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.stderr index 69fa27c9c09..f189d0483d1 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.stderr @@ -19,17 +19,17 @@ LL | fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { = note: BACKTRACE: = note: inside `std::boxed::Box::<i32>::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::boxed::Box::<i32>::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside closure at $DIR/newtype_retagging.rs:LL:CC +note: inside closure --> $DIR/newtype_retagging.rs:LL:CC | LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ -note: inside `dealloc_while_running::<[closure@$DIR/newtype_retagging.rs:LL:CC]>` at $DIR/newtype_retagging.rs:LL:CC +note: inside `dealloc_while_running::<[closure@$DIR/newtype_retagging.rs:LL:CC]>` --> $DIR/newtype_retagging.rs:LL:CC | LL | dealloc(); | ^^^^^^^^^ -note: inside `main` at $DIR/newtype_retagging.rs:LL:CC +note: inside `main` --> $DIR/newtype_retagging.rs:LL:CC | LL | / dealloc_while_running( diff --git a/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr b/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr index 6415af1e18b..7d58d1aebbe 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr @@ -21,7 +21,7 @@ LL | *val = 2; // this invalidates any raw ptrs `fun1` might have created. | ^^^^^^^^ = note: BACKTRACE: = note: inside `fun2` at $DIR/pointer_smuggling.rs:LL:CC -note: inside `main` at $DIR/pointer_smuggling.rs:LL:CC +note: inside `main` --> $DIR/pointer_smuggling.rs:LL:CC | LL | fun2(); // if they now use a raw ptr they break our reference diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr index f25d689524d..5dc936f0707 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr @@ -8,7 +8,7 @@ LL | *p = 5; = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `thread_2` at $DIR/retag_data_race_read.rs:LL:CC -note: inside closure at $DIR/retag_data_race_read.rs:LL:CC +note: inside closure --> $DIR/retag_data_race_read.rs:LL:CC | LL | let t2 = std::thread::spawn(move || thread_2(p)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.stderr index f97e6bb11e9..03c24503564 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.stderr @@ -8,7 +8,7 @@ LL | *p = 5; = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `thread_2` at $DIR/retag_data_race_write.rs:LL:CC -note: inside closure at $DIR/retag_data_race_write.rs:LL:CC +note: inside closure --> $DIR/retag_data_race_write.rs:LL:CC | LL | let t2 = std::thread::spawn(move || thread_2(p)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr index 9deb0c41742..1b28f780c1c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr @@ -21,7 +21,7 @@ LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ = note: BACKTRACE: = note: inside `foo` at $DIR/return_invalid_mut.rs:LL:CC -note: inside `main` at $DIR/return_invalid_mut.rs:LL:CC +note: inside `main` --> $DIR/return_invalid_mut.rs:LL:CC | LL | foo(&mut (1, 2)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr index c0ff35ebcde..db14dcafa00 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr @@ -21,7 +21,7 @@ LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ = note: BACKTRACE: = note: inside `foo` at $DIR/return_invalid_mut_option.rs:LL:CC -note: inside `main` at $DIR/return_invalid_mut_option.rs:LL:CC +note: inside `main` --> $DIR/return_invalid_mut_option.rs:LL:CC | LL | match foo(&mut (1, 2)) { diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr index 9abf43c29f0..81ed4218aad 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr @@ -21,7 +21,7 @@ LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ = note: BACKTRACE: = note: inside `foo` at $DIR/return_invalid_mut_tuple.rs:LL:CC -note: inside `main` at $DIR/return_invalid_mut_tuple.rs:LL:CC +note: inside `main` --> $DIR/return_invalid_mut_tuple.rs:LL:CC | LL | foo(&mut (1, 2)).0; diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr.stderr index dd651517c2f..9c8cc50b2d7 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr.stderr @@ -21,7 +21,7 @@ LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = note: BACKTRACE: = note: inside `foo` at $DIR/return_invalid_shr.rs:LL:CC -note: inside `main` at $DIR/return_invalid_shr.rs:LL:CC +note: inside `main` --> $DIR/return_invalid_shr.rs:LL:CC | LL | foo(&mut (1, 2)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr index 6066bf89f5d..00ce6f6cd5f 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_option.stderr @@ -21,7 +21,7 @@ LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = note: BACKTRACE: = note: inside `foo` at $DIR/return_invalid_shr_option.rs:LL:CC -note: inside `main` at $DIR/return_invalid_shr_option.rs:LL:CC +note: inside `main` --> $DIR/return_invalid_shr_option.rs:LL:CC | LL | match foo(&mut (1, 2)) { diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr index 52d365246a7..bbd17b1284c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_shr_tuple.stderr @@ -21,7 +21,7 @@ LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = note: BACKTRACE: = note: inside `foo` at $DIR/return_invalid_shr_tuple.rs:LL:CC -note: inside `main` at $DIR/return_invalid_shr_tuple.rs:LL:CC +note: inside `main` --> $DIR/return_invalid_shr_tuple.rs:LL:CC | LL | foo(&mut (1, 2)).0; diff --git a/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.stderr b/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.stderr index 0818d07da48..fe0ac211318 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.stderr @@ -16,12 +16,12 @@ LL | *(x as *const i32 as *mut i32) = 7; | ^ = note: BACKTRACE: = note: inside `unknown_code` at $DIR/shr_frozen_violation1.rs:LL:CC -note: inside `foo` at $DIR/shr_frozen_violation1.rs:LL:CC +note: inside `foo` --> $DIR/shr_frozen_violation1.rs:LL:CC | LL | unknown_code(&*x); | ^^^^^^^^^^^^^^^^^ -note: inside `main` at $DIR/shr_frozen_violation1.rs:LL:CC +note: inside `main` --> $DIR/shr_frozen_violation1.rs:LL:CC | LL | println!("{}", foo(&mut 0)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/zst_slice.stderr b/src/tools/miri/tests/fail/stacked_borrows/zst_slice.stderr index 86f1da1f70a..e134ee2845d 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/zst_slice.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/zst_slice.stderr @@ -16,7 +16,7 @@ LL | assert_eq!(*s.get_unchecked(1), 2); | ^^^^^^^^^^^^^^^^^^ = note: BACKTRACE: = note: inside `core::slice::<impl [i32]>::get_unchecked::<usize>` at RUSTLIB/core/src/slice/mod.rs:LL:CC -note: inside `main` at $DIR/zst_slice.rs:LL:CC +note: inside `main` --> $DIR/zst_slice.rs:LL:CC | LL | assert_eq!(*s.get_unchecked(1), 2); diff --git a/src/tools/miri/tests/fail/uninit_buffer.stderr b/src/tools/miri/tests/fail/uninit_buffer.stderr index a543d59addb..8da532cfff0 100644 --- a/src/tools/miri/tests/fail/uninit_buffer.stderr +++ b/src/tools/miri/tests/fail/uninit_buffer.stderr @@ -9,7 +9,7 @@ LL | let mut order = unsafe { memcmp(left.as_ptr(), right.as_ptr(), len) = note: BACKTRACE: = note: inside `<u8 as core::slice::cmp::SliceOrd>::compare` at RUSTLIB/core/src/slice/cmp.rs:LL:CC = note: inside `core::slice::cmp::<impl std::cmp::Ord for [u8]>::cmp` at RUSTLIB/core/src/slice/cmp.rs:LL:CC -note: inside `main` at $DIR/uninit_buffer.rs:LL:CC +note: inside `main` --> $DIR/uninit_buffer.rs:LL:CC | LL | drop(slice1.cmp(slice2)); diff --git a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.stderr b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.stderr index 715d76aa1c2..210fc8e109a 100644 --- a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.stderr +++ b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.stderr @@ -9,7 +9,7 @@ LL | let mut order = unsafe { memcmp(left.as_ptr(), right.as_ptr(), len) = note: BACKTRACE: = note: inside `<u8 as core::slice::cmp::SliceOrd>::compare` at RUSTLIB/core/src/slice/cmp.rs:LL:CC = note: inside `core::slice::cmp::<impl std::cmp::Ord for [u8]>::cmp` at RUSTLIB/core/src/slice/cmp.rs:LL:CC -note: inside `main` at $DIR/uninit_buffer_with_provenance.rs:LL:CC +note: inside `main` --> $DIR/uninit_buffer_with_provenance.rs:LL:CC | LL | drop(slice1.cmp(slice2)); diff --git a/src/tools/miri/tests/pass/box.stderr b/src/tools/miri/tests/pass/box.stderr index 0001a8dd6eb..4c2fb40e110 100644 --- a/src/tools/miri/tests/pass/box.stderr +++ b/src/tools/miri/tests/pass/box.stderr @@ -12,7 +12,7 @@ LL | let r2 = ((r as usize) + 0) as *mut i32; = help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning. = note: BACKTRACE: = note: inside `into_raw` at $DIR/box.rs:LL:CC -note: inside `main` at $DIR/box.rs:LL:CC +note: inside `main` --> $DIR/box.rs:LL:CC | LL | into_raw(); @@ -25,7 +25,7 @@ LL | let r = ((u.as_ptr() as usize) + 0) as *mut i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | = note: inside `into_unique` at $DIR/box.rs:LL:CC -note: inside `main` at $DIR/box.rs:LL:CC +note: inside `main` --> $DIR/box.rs:LL:CC | LL | into_unique(); diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index ff7a219d9bd..7ee8c5d3bad 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -219,6 +219,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "snap", "stable_deref_trait", "stacker", + "static_assertions", "syn", "synstructure", "tempfile", @@ -239,6 +240,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "tracing-log", "tracing-subscriber", "tracing-tree", + "twox-hash", "type-map", "typenum", "unic-char-property", diff --git a/src/version b/src/version index 65ee0959841..ee2f4ca9130 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.67.0 +1.68.0 |
