From 36cd4fab22afc9e08d03fb9ce91049553d0e78ad Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 25 Mar 2022 02:44:16 -0400 Subject: [PATCH 001/124] Add `round_ties_even` to `f32` and `f64` --- src/intrinsics/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 0302b843aa226..4851c3fdcb7a7 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -297,6 +297,8 @@ fn codegen_float_intrinsic_call<'tcx>( sym::truncf64 => ("trunc", 1, fx.tcx.types.f64), sym::roundf32 => ("roundf", 1, fx.tcx.types.f32), sym::roundf64 => ("round", 1, fx.tcx.types.f64), + sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32), + sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64), sym::sinf32 => ("sinf", 1, fx.tcx.types.f32), sym::sinf64 => ("sin", 1, fx.tcx.types.f64), sym::cosf32 => ("cosf", 1, fx.tcx.types.f32), From 20d6292596c86b0610074def2f426a25443ecb6d Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Mon, 7 Nov 2022 13:10:36 -0500 Subject: [PATCH 002/124] Use rint instead of roundeven Use rint intrinsic instead of roundeven to impement `round_ties_even`. They do the same thing when rounding mode is default, which Rust assumes. And `rint` has better platform support. Keeps `roundeven` around in `core::intrinsics`, it's doing no harm there. --- src/intrinsics/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 4851c3fdcb7a7..ff9447a748460 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -295,6 +295,8 @@ fn codegen_float_intrinsic_call<'tcx>( sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64), sym::truncf32 => ("truncf", 1, fx.tcx.types.f32), sym::truncf64 => ("trunc", 1, fx.tcx.types.f64), + sym::rintf32 => ("rintf", 1, fx.tcx.types.f32), + sym::rintf64 => ("rint", 1, fx.tcx.types.f64), sym::roundf32 => ("roundf", 1, fx.tcx.types.f32), sym::roundf64 => ("round", 1, fx.tcx.types.f64), sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32), From 56951e4f2b136fbf8b6a93fd1577779855052a62 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Feb 2023 12:38:16 +0100 Subject: [PATCH 003/124] Merge commit '7d53619064ab7045c383644cb445052d2a3d46db' into sync_cg_clif-2023-02-09 --- .github/workflows/main.yml | 146 ++++++++++++++++++++++---- build_sysroot/Cargo.lock | 4 +- build_system/abi_cafe.rs | 8 +- build_system/bench.rs | 32 +++--- build_system/build_backend.rs | 6 +- build_system/build_sysroot.rs | 3 + build_system/mod.rs | 8 +- build_system/prepare.rs | 18 ++-- build_system/tests.rs | 5 - build_system/utils.rs | 18 +++- config.txt | 1 - rust-toolchain | 2 +- scripts/test_rustc_tests.sh | 1 + src/abi/comments.rs | 4 +- src/allocator.rs | 75 +++----------- src/base.rs | 91 ++++++++++------ src/common.rs | 38 +++++++ src/compiler_builtins.rs | 38 ++++++- src/config.rs | 8 -- src/driver/aot.rs | 130 ++++++++++++----------- src/driver/jit.rs | 46 +++++---- src/driver/mod.rs | 15 +-- src/global_asm.rs | 43 +++++++- src/inline_asm.rs | 189 +++++++++++++++++++++++++--------- src/intrinsics/mod.rs | 31 +++--- src/value_and_place.rs | 11 +- 26 files changed, 640 insertions(+), 331 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c0daf69e98e91..9d3ed3ac5d0c3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,6 +21,7 @@ jobs: cargo fmt --check rustfmt --check build_system/mod.rs + build: runs-on: ${{ matrix.os }} timeout-minutes: 60 @@ -33,7 +34,7 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-20.04 # FIXME switch to ubuntu-22.04 once #1303 is fixed + - os: ubuntu-latest env: TARGET_TRIPLE: x86_64-unknown-linux-gnu - os: macos-latest @@ -112,23 +113,6 @@ jobs: TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }} run: ./y.rs test - - name: Package prebuilt cg_clif - run: tar cvfJ cg_clif.tar.xz dist - - - name: Upload prebuilt cg_clif - if: matrix.os == 'windows-latest' || matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu' - uses: actions/upload-artifact@v3 - with: - name: cg_clif-${{ matrix.env.TARGET_TRIPLE }} - path: cg_clif.tar.xz - - - name: Upload prebuilt cg_clif (cross compile) - if: matrix.os != 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' - uses: actions/upload-artifact@v3 - with: - name: cg_clif-${{ runner.os }}-cross-x86_64-mingw - path: cg_clif.tar.xz - abi_cafe: runs-on: ${{ matrix.os }} @@ -185,3 +169,129 @@ jobs: env: TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }} run: ./y.rs abi-cafe + + + bench: + runs-on: ubuntu-latest + timeout-minutes: 60 + + defaults: + run: + shell: bash + + steps: + - uses: actions/checkout@v3 + + - name: Cache cargo target dir + uses: actions/cache@v3 + with: + path: build/cg_clif + key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + + - name: Cache cargo bin dir + uses: actions/cache@v3 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-bin-dir-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + + - name: Use sparse cargo registry + run: | + cat >> ~/.cargo/config.toml <> ~/.cargo/config.toml < { clone_repo_shallow_github( diff --git a/build_system/tests.rs b/build_system/tests.rs index dcfadd737566e..e9486888f86a4 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -1,4 +1,3 @@ -use super::bench::SIMPLE_RAYTRACER; use super::build_sysroot::{self, SYSROOT_SRC}; use super::config; use super::path::{Dirs, RelPath}; @@ -134,10 +133,6 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ spawn_and_wait(build_cmd); } }), - TestCase::custom("test.simple-raytracer", &|runner| { - SIMPLE_RAYTRACER.clean(&runner.dirs); - spawn_and_wait(SIMPLE_RAYTRACER.build(&runner.target_compiler, &runner.dirs)); - }), TestCase::custom("test.libcore", &|runner| { LIBCORE_TESTS.clean(&runner.dirs); diff --git a/build_system/utils.rs b/build_system/utils.rs index da2a94a0a4ff8..abc5bab494224 100644 --- a/build_system/utils.rs +++ b/build_system/utils.rs @@ -121,10 +121,18 @@ impl CargoProject { } #[must_use] - pub(crate) fn fetch(&self, cargo: impl AsRef, dirs: &Dirs) -> Command { + pub(crate) fn fetch( + &self, + cargo: impl AsRef, + rustc: impl AsRef, + dirs: &Dirs, + ) -> Command { let mut cmd = Command::new(cargo.as_ref()); - cmd.arg("fetch").arg("--manifest-path").arg(self.manifest_path(dirs)); + cmd.env("RUSTC", rustc.as_ref()) + .arg("fetch") + .arg("--manifest-path") + .arg(self.manifest_path(dirs)); cmd } @@ -271,5 +279,9 @@ pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) { } pub(crate) fn is_ci() -> bool { - env::var("CI").as_deref() == Ok("true") + env::var("CI").is_ok() +} + +pub(crate) fn is_ci_opt() -> bool { + env::var("CI_OPT").is_ok() } diff --git a/config.txt b/config.txt index d49cc90791a5d..d6e3924a24d64 100644 --- a/config.txt +++ b/config.txt @@ -44,7 +44,6 @@ aot.issue-72793 testsuite.extended_sysroot test.rust-random/rand -test.simple-raytracer test.libcore test.regex-shootout-regex-dna test.regex diff --git a/rust-toolchain b/rust-toolchain index 77345b9a17c6e..40fb54b915992 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-01-20" +channel = "nightly-2023-02-06" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 07c9ae6ee9ff2..e14a129dbc2d0 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -91,6 +91,7 @@ rm tests/ui/proc-macro/proc-macro-deprecated-attr.rs # same rm tests/ui/proc-macro/quote-debug.rs # same rm tests/ui/proc-macro/no-missing-docs.rs # same rm tests/ui/rust-2018/proc-macro-crate-in-paths.rs # same +rm tests/ui/proc-macro/allowed-signatures.rs # same # doesn't work due to the way the rustc test suite is invoked. # should work when using ./x.py test the way it is intended diff --git a/src/abi/comments.rs b/src/abi/comments.rs index 7f4619b5c940b..abf63e33c3537 100644 --- a/src/abi/comments.rs +++ b/src/abi/comments.rs @@ -98,12 +98,12 @@ pub(super) fn add_local_place_comments<'tcx>( } CPlaceInner::VarPair(place_local, var1, var2) => { assert_eq!(local, place_local); - ("ssa", Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index()))) + ("ssa", Cow::Owned(format!("var=({}, {})", var1.index(), var2.index()))) } CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(), CPlaceInner::Addr(ptr, meta) => { let meta = if let Some(meta) = meta { - Cow::Owned(format!(",meta={}", meta)) + Cow::Owned(format!("meta={}", meta)) } else { Cow::Borrowed("") }; diff --git a/src/allocator.rs b/src/allocator.rs index 8508227179ac6..1c73957ca571c 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -70,37 +70,13 @@ fn codegen_inner( params: arg_tys.iter().cloned().map(AbiParam::new).collect(), returns: output.into_iter().map(AbiParam::new).collect(), }; - - let caller_name = format!("__rust_{}", method.name); - let callee_name = kind.fn_name(method.name); - - let func_id = module.declare_function(&caller_name, Linkage::Export, &sig).unwrap(); - - let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap(); - - let mut ctx = Context::new(); - ctx.func.signature = sig.clone(); - { - let mut func_ctx = FunctionBuilderContext::new(); - let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); - - let block = bcx.create_block(); - bcx.switch_to_block(block); - let args = arg_tys - .into_iter() - .map(|ty| bcx.append_block_param(block, ty)) - .collect::>(); - - let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func); - let call_inst = bcx.ins().call(callee_func_ref, &args); - let results = bcx.inst_results(call_inst).to_vec(); // Clone to prevent borrow error - - bcx.ins().return_(&results); - bcx.seal_all_blocks(); - bcx.finalize(); - } - module.define_function(func_id, &mut ctx).unwrap(); - unwind_context.add_function(func_id, &ctx, module.isa()); + crate::common::create_wrapper_function( + module, + unwind_context, + sig, + &format!("__rust_{}", method.name), + &kind.fn_name(method.name), + ); } let sig = Signature { @@ -108,36 +84,13 @@ fn codegen_inner( params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], returns: vec![], }; - - let callee_name = alloc_error_handler_kind.fn_name(sym::oom); - - let func_id = - module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap(); - - let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap(); - - let mut ctx = Context::new(); - ctx.func.signature = sig; - { - let mut func_ctx = FunctionBuilderContext::new(); - let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); - - let block = bcx.create_block(); - bcx.switch_to_block(block); - let args = (&[usize_ty, usize_ty]) - .iter() - .map(|&ty| bcx.append_block_param(block, ty)) - .collect::>(); - - let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func); - bcx.ins().call(callee_func_ref, &args); - - bcx.ins().trap(TrapCode::UnreachableCodeReached); - bcx.seal_all_blocks(); - bcx.finalize(); - } - module.define_function(func_id, &mut ctx).unwrap(); - unwind_context.add_function(func_id, &ctx, module.isa()); + crate::common::create_wrapper_function( + module, + unwind_context, + sig, + "__rust_alloc_error_handler", + &alloc_error_handler_kind.fn_name(sym::oom), + ); let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap(); let mut data_ctx = DataContext::new(); diff --git a/src/base.rs b/src/base.rs index dffb2ed8f4f39..189d952a92f17 100644 --- a/src/base.rs +++ b/src/base.rs @@ -21,23 +21,6 @@ pub(crate) struct CodegenedFunction { func_debug_cx: Option, } -#[cfg_attr(not(feature = "jit"), allow(dead_code))] -pub(crate) fn codegen_and_compile_fn<'tcx>( - tcx: TyCtxt<'tcx>, - cx: &mut crate::CodegenCx, - cached_context: &mut Context, - module: &mut dyn Module, - instance: Instance<'tcx>, -) { - let _inst_guard = - crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name)); - - let cached_func = std::mem::replace(&mut cached_context.func, Function::new()); - let codegened_func = codegen_fn(tcx, cx, cached_func, module, instance); - - compile_fn(cx, cached_context, module, codegened_func); -} - pub(crate) fn codegen_fn<'tcx>( tcx: TyCtxt<'tcx>, cx: &mut crate::CodegenCx, @@ -47,6 +30,9 @@ pub(crate) fn codegen_fn<'tcx>( ) -> CodegenedFunction { debug_assert!(!instance.substs.needs_infer()); + let symbol_name = tcx.symbol_name(instance).name.to_string(); + let _timer = tcx.prof.generic_activity_with_arg("codegen fn", &*symbol_name); + let mir = tcx.instance_mir(instance.def); let _mir_guard = crate::PrintOnPanic(|| { let mut buf = Vec::new(); @@ -58,7 +44,6 @@ pub(crate) fn codegen_fn<'tcx>( }); // Declare function - let symbol_name = tcx.symbol_name(instance).name.to_string(); let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance); let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap(); @@ -112,7 +97,7 @@ pub(crate) fn codegen_fn<'tcx>( next_ssa_var: 0, }; - tcx.sess.time("codegen clif ir", || codegen_fn_body(&mut fx, start_block)); + tcx.prof.generic_activity("codegen clif ir").run(|| codegen_fn_body(&mut fx, start_block)); fx.bcx.seal_all_blocks(); fx.bcx.finalize(); @@ -146,6 +131,9 @@ pub(crate) fn compile_fn( module: &mut dyn Module, codegened_func: CodegenedFunction, ) { + let _timer = + cx.profiler.generic_activity_with_arg("compile function", &*codegened_func.symbol_name); + let clif_comments = codegened_func.clif_comments; // Store function in context @@ -191,9 +179,30 @@ pub(crate) fn compile_fn( }; // Define function - cx.profiler.verbose_generic_activity("define function").run(|| { + cx.profiler.generic_activity("define function").run(|| { context.want_disasm = cx.should_write_ir; module.define_function(codegened_func.func_id, context).unwrap(); + + if cx.profiler.enabled() { + let mut recording_args = false; + cx.profiler + .generic_activity_with_arg_recorder( + "define function (clif pass timings)", + |recorder| { + let pass_times = cranelift_codegen::timing::take_current(); + // Replace newlines with | as measureme doesn't allow control characters like + // newlines inside strings. + recorder.record_arg(format!("{}", pass_times).replace("\n", " | ")); + recording_args = true; + }, + ) + .run(|| { + if recording_args { + // Wait a tiny bit to ensure chrome's profiler doesn't hide the event + std::thread::sleep(std::time::Duration::from_nanos(2)) + } + }); + } }); if cx.should_write_ir { @@ -220,7 +229,7 @@ pub(crate) fn compile_fn( let isa = module.isa(); let debug_context = &mut cx.debug_context; let unwind_context = &mut cx.unwind_context; - cx.profiler.verbose_generic_activity("generate debug info").run(|| { + cx.profiler.generic_activity("generate debug info").run(|| { if let Some(debug_context) = debug_context { codegened_func.func_debug_cx.unwrap().finalize( debug_context, @@ -237,7 +246,7 @@ pub(crate) fn verify_func( writer: &crate::pretty_clif::CommentWriter, func: &Function, ) { - tcx.sess.time("verify clif ir", || { + tcx.prof.generic_activity("verify clif ir").run(|| { let flags = cranelift_codegen::settings::Flags::new(cranelift_codegen::settings::builder()); match cranelift_codegen::verify_function(&func, &flags) { Ok(_) => {} @@ -273,7 +282,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); return; } - fx.tcx.sess.time("codegen prelude", || crate::abi::codegen_fn_prelude(fx, start_block)); + fx.tcx + .prof + .generic_activity("codegen prelude") + .run(|| crate::abi::codegen_fn_prelude(fx, start_block)); for (bb, bb_data) in fx.mir.basic_blocks.iter_enumerated() { let block = fx.get_block(bb); @@ -434,7 +446,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { cleanup: _, from_hir_call: _, } => { - fx.tcx.sess.time("codegen call", || { + fx.tcx.prof.generic_activity("codegen call").run(|| { crate::abi::codegen_terminator_call( fx, mir::SourceInfo { span: *fn_span, ..source_info }, @@ -778,17 +790,30 @@ fn codegen_stmt<'tcx>( let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into()); lval.write_cvalue(fx, val); } - Rvalue::Aggregate(ref kind, ref operands) => match kind.as_ref() { - AggregateKind::Array(_ty) => { - for (i, operand) in operands.iter().enumerate() { - let operand = codegen_operand(fx, operand); - let index = fx.bcx.ins().iconst(fx.pointer_type, i as i64); - let to = lval.place_index(fx, index); - to.write_cvalue(fx, operand); + Rvalue::Aggregate(ref kind, ref operands) => { + let (variant_index, variant_dest, active_field_index) = match **kind { + mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => { + let variant_dest = lval.downcast_variant(fx, variant_index); + (variant_index, variant_dest, active_field_index) } + _ => (VariantIdx::from_u32(0), lval, None), + }; + if active_field_index.is_some() { + assert_eq!(operands.len(), 1); + } + for (i, operand) in operands.iter().enumerate() { + let operand = codegen_operand(fx, operand); + let field_index = active_field_index.unwrap_or(i); + let to = if let mir::AggregateKind::Array(_) = **kind { + let index = fx.bcx.ins().iconst(fx.pointer_type, field_index as i64); + variant_dest.place_index(fx, index) + } else { + variant_dest.place_field(fx, mir::Field::new(field_index)) + }; + to.write_cvalue(fx, operand); } - _ => unreachable!("shouldn't exist at codegen {:?}", to_place_and_rval.1), - }, + crate::discriminant::codegen_set_discriminant(fx, lval, variant_index); + } } } StatementKind::StorageLive(_) diff --git a/src/common.rs b/src/common.rs index f41af3a9e6366..a8be0d32cc8c7 100644 --- a/src/common.rs +++ b/src/common.rs @@ -254,6 +254,44 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool { } } +pub(crate) fn create_wrapper_function( + module: &mut dyn Module, + unwind_context: &mut UnwindContext, + sig: Signature, + wrapper_name: &str, + callee_name: &str, +) { + let wrapper_func_id = module.declare_function(wrapper_name, Linkage::Export, &sig).unwrap(); + let callee_func_id = module.declare_function(callee_name, Linkage::Import, &sig).unwrap(); + + let mut ctx = Context::new(); + ctx.func.signature = sig; + { + let mut func_ctx = FunctionBuilderContext::new(); + let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); + + let block = bcx.create_block(); + bcx.switch_to_block(block); + let func = &mut bcx.func.stencil; + let args = func + .signature + .params + .iter() + .map(|param| func.dfg.append_block_param(block, param.value_type)) + .collect::>(); + + let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func); + let call_inst = bcx.ins().call(callee_func_ref, &args); + let results = bcx.inst_results(call_inst).to_vec(); // Clone to prevent borrow error + + bcx.ins().return_(&results); + bcx.seal_all_blocks(); + bcx.finalize(); + } + module.define_function(wrapper_func_id, &mut ctx).unwrap(); + unwind_context.add_function(wrapper_func_id, &ctx, module.isa()); +} + pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { pub(crate) cx: &'clif mut crate::CodegenCx, pub(crate) module: &'m mut dyn Module, diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs index c6a247cf59eed..8a53baa763a7d 100644 --- a/src/compiler_builtins.rs +++ b/src/compiler_builtins.rs @@ -1,14 +1,33 @@ +#[cfg(all(unix, feature = "jit"))] +use std::ffi::c_int; +#[cfg(feature = "jit")] +use std::ffi::c_void; + +// FIXME replace with core::ffi::c_size_t once stablized +#[allow(non_camel_case_types)] +#[cfg(feature = "jit")] +type size_t = usize; + macro_rules! builtin_functions { - ($register:ident; $(fn $name:ident($($arg_name:ident: $arg_ty:ty),*) -> $ret_ty:ty;)*) => { + ( + $register:ident; + $( + $(#[$attr:meta])? + fn $name:ident($($arg_name:ident: $arg_ty:ty),*) -> $ret_ty:ty; + )* + ) => { #[cfg(feature = "jit")] #[allow(improper_ctypes)] extern "C" { - $(fn $name($($arg_name: $arg_ty),*) -> $ret_ty;)* + $( + $(#[$attr])? + fn $name($($arg_name: $arg_ty),*) -> $ret_ty; + )* } #[cfg(feature = "jit")] pub(crate) fn $register(builder: &mut cranelift_jit::JITBuilder) { - for (name, val) in [$((stringify!($name), $name as *const u8)),*] { + for (name, val) in [$($(#[$attr])? (stringify!($name), $name as *const u8)),*] { builder.symbol(name, val); } } @@ -40,4 +59,17 @@ builtin_functions! { fn __fixdfti(f: f64) -> i128; fn __fixunssfti(f: f32) -> u128; fn __fixunsdfti(f: f64) -> u128; + + // allocator + // NOTE: These need to be mentioned here despite not being part of compiler_builtins because + // newer glibc resolve dlsym("malloc") to libc.so despite the override in the rustc binary to + // use jemalloc. Libraries opened with dlopen still get the jemalloc version, causing multiple + // allocators to be mixed, resulting in a crash. + fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + #[cfg(unix)] + fn posix_memalign(memptr: *mut *mut c_void, align: size_t, size: size_t) -> c_int; + fn malloc(size: size_t) -> *mut c_void; + fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; + fn free(p: *mut c_void) -> (); + } diff --git a/src/config.rs b/src/config.rs index 45522fb1a4cab..263401e1c4b83 100644 --- a/src/config.rs +++ b/src/config.rs @@ -42,12 +42,6 @@ pub struct BackendConfig { /// Defaults to the value of `CG_CLIF_JIT_ARGS`. pub jit_args: Vec, - /// Display the time it took to perform codegen for a crate. - /// - /// Defaults to true when the `CG_CLIF_DISPLAY_CG_TIME` env var is set to 1 or false otherwise. - /// Can be set using `-Cllvm-args=display_cg_time=...`. - pub display_cg_time: bool, - /// Enable the Cranelift ir verifier for all compilation passes. If not set it will only run /// once before passing the clif ir to Cranelift for compilation. /// @@ -73,7 +67,6 @@ impl Default for BackendConfig { let args = std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new()); args.split(' ').map(|arg| arg.to_string()).collect() }, - display_cg_time: bool_env_var("CG_CLIF_DISPLAY_CG_TIME"), enable_verifier: cfg!(debug_assertions) || bool_env_var("CG_CLIF_ENABLE_VERIFIER"), disable_incr_cache: bool_env_var("CG_CLIF_DISABLE_INCR_CACHE"), } @@ -92,7 +85,6 @@ impl BackendConfig { if let Some((name, value)) = opt.split_once('=') { match name { "mode" => config.codegen_mode = value.parse()?, - "display_cg_time" => config.display_cg_time = parse_bool(name, value)?, "enable_verifier" => config.enable_verifier = parse_bool(name, value)?, "disable_incr_cache" => config.disable_incr_cache = parse_bool(name, value)?, _ => return Err(format!("Unknown option `{}`", name)), diff --git a/src/driver/aot.rs b/src/driver/aot.rs index d4494a9e45de4..58b01dfb5b0ec 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -272,25 +272,25 @@ fn module_codegen( ConcurrencyLimiterToken, ), ) -> OngoingModuleCodegen { - let (cgu_name, mut cx, mut module, codegened_functions) = tcx.sess.time("codegen cgu", || { - let cgu = tcx.codegen_unit(cgu_name); - let mono_items = cgu.items_in_deterministic_order(tcx); - - let mut module = make_module(tcx.sess, &backend_config, cgu_name.as_str().to_string()); - - let mut cx = crate::CodegenCx::new( - tcx, - backend_config.clone(), - module.isa(), - tcx.sess.opts.debuginfo != DebugInfo::None, - cgu_name, - ); - super::predefine_mono_items(tcx, &mut module, &mono_items); - let mut codegened_functions = vec![]; - for (mono_item, _) in mono_items { - match mono_item { - MonoItem::Fn(inst) => { - tcx.sess.time("codegen fn", || { + let (cgu_name, mut cx, mut module, codegened_functions) = + tcx.prof.verbose_generic_activity_with_arg("codegen cgu", cgu_name.as_str()).run(|| { + let cgu = tcx.codegen_unit(cgu_name); + let mono_items = cgu.items_in_deterministic_order(tcx); + + let mut module = make_module(tcx.sess, &backend_config, cgu_name.as_str().to_string()); + + let mut cx = crate::CodegenCx::new( + tcx, + backend_config.clone(), + module.isa(), + tcx.sess.opts.debuginfo != DebugInfo::None, + cgu_name, + ); + super::predefine_mono_items(tcx, &mut module, &mono_items); + let mut codegened_functions = vec![]; + for (mono_item, _) in mono_items { + match mono_item { + MonoItem::Fn(inst) => { let codegened_function = crate::base::codegen_fn( tcx, &mut cx, @@ -299,53 +299,68 @@ fn module_codegen( inst, ); codegened_functions.push(codegened_function); - }); - } - MonoItem::Static(def_id) => { - crate::constant::codegen_static(tcx, &mut module, def_id) - } - MonoItem::GlobalAsm(item_id) => { - crate::global_asm::codegen_global_asm_item(tcx, &mut cx.global_asm, item_id); + } + MonoItem::Static(def_id) => { + crate::constant::codegen_static(tcx, &mut module, def_id) + } + MonoItem::GlobalAsm(item_id) => { + crate::global_asm::codegen_global_asm_item( + tcx, + &mut cx.global_asm, + item_id, + ); + } } } - } - crate::main_shim::maybe_create_entry_wrapper( - tcx, - &mut module, - &mut cx.unwind_context, - false, - cgu.is_primary(), - ); + crate::main_shim::maybe_create_entry_wrapper( + tcx, + &mut module, + &mut cx.unwind_context, + false, + cgu.is_primary(), + ); - let cgu_name = cgu.name().as_str().to_owned(); + let cgu_name = cgu.name().as_str().to_owned(); - (cgu_name, cx, module, codegened_functions) - }); + (cgu_name, cx, module, codegened_functions) + }); OngoingModuleCodegen::Async(std::thread::spawn(move || { - cx.profiler.clone().verbose_generic_activity("compile functions").run(|| { - let mut cached_context = Context::new(); - for codegened_func in codegened_functions { - crate::base::compile_fn(&mut cx, &mut cached_context, &mut module, codegened_func); - } - }); + cx.profiler.clone().verbose_generic_activity_with_arg("compile functions", &*cgu_name).run( + || { + let mut cached_context = Context::new(); + for codegened_func in codegened_functions { + crate::base::compile_fn( + &mut cx, + &mut cached_context, + &mut module, + codegened_func, + ); + } + }, + ); - let global_asm_object_file = - cx.profiler.verbose_generic_activity("compile assembly").run(|| { + let global_asm_object_file = cx + .profiler + .verbose_generic_activity_with_arg("compile assembly", &*cgu_name) + .run(|| { crate::global_asm::compile_global_asm(&global_asm_config, &cgu_name, &cx.global_asm) })?; - let codegen_result = cx.profiler.verbose_generic_activity("write object file").run(|| { - emit_cgu( - &global_asm_config.output_filenames, - &cx.profiler, - cgu_name, - module, - cx.debug_context, - cx.unwind_context, - global_asm_object_file, - ) - }); + let codegen_result = cx + .profiler + .verbose_generic_activity_with_arg("write object file", &*cgu_name) + .run(|| { + emit_cgu( + &global_asm_config.output_filenames, + &cx.profiler, + cgu_name, + module, + cx.debug_context, + cx.unwind_context, + global_asm_object_file, + ) + }); std::mem::drop(token); codegen_result })) @@ -375,7 +390,7 @@ pub(crate) fn run_aot( let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, cgus.len()); - let modules = super::time(tcx, backend_config.display_cg_time, "codegen mono items", || { + let modules = tcx.sess.time("codegen mono items", || { cgus.iter() .map(|cgu| { let cgu_reuse = if backend_config.disable_incr_cache { @@ -437,7 +452,6 @@ pub(crate) fn run_aot( }; let metadata_module = if need_metadata_module { - let _timer = tcx.prof.generic_activity("codegen crate metadata"); let (metadata_cgu_name, tmp_file) = tcx.sess.time("write compressed metadata", || { use rustc_middle::mir::mono::CodegenUnitNameBuilder; diff --git a/src/driver/jit.rs b/src/driver/jit.rs index be1b8c9ead3bf..8b5a2da2c5944 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -121,22 +121,20 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { .into_iter() .collect::>(); - super::time(tcx, backend_config.display_cg_time, "codegen mono items", || { + tcx.sess.time("codegen mono items", || { super::predefine_mono_items(tcx, &mut jit_module, &mono_items); for (mono_item, _) in mono_items { match mono_item { MonoItem::Fn(inst) => match backend_config.codegen_mode { CodegenMode::Aot => unreachable!(), CodegenMode::Jit => { - tcx.sess.time("codegen fn", || { - crate::base::codegen_and_compile_fn( - tcx, - &mut cx, - &mut cached_context, - &mut jit_module, - inst, - ) - }); + codegen_and_compile_fn( + tcx, + &mut cx, + &mut cached_context, + &mut jit_module, + inst, + ); } CodegenMode::JitLazy => { codegen_shim(tcx, &mut cx, &mut cached_context, &mut jit_module, inst) @@ -219,6 +217,24 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { } } +pub(crate) fn codegen_and_compile_fn<'tcx>( + tcx: TyCtxt<'tcx>, + cx: &mut crate::CodegenCx, + cached_context: &mut Context, + module: &mut dyn Module, + instance: Instance<'tcx>, +) { + tcx.prof.generic_activity("codegen and compile fn").run(|| { + let _inst_guard = + crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name)); + + let cached_func = std::mem::replace(&mut cached_context.func, Function::new()); + let codegened_func = crate::base::codegen_fn(tcx, cx, cached_func, module, instance); + + crate::base::compile_fn(cx, cached_context, module, codegened_func); + }); +} + extern "C" fn clif_jit_fn( instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8, @@ -271,15 +287,7 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> false, Symbol::intern("dummy_cgu_name"), ); - tcx.sess.time("codegen fn", || { - crate::base::codegen_and_compile_fn( - tcx, - &mut cx, - &mut Context::new(), - jit_module, - instance, - ) - }); + codegen_and_compile_fn(tcx, &mut cx, &mut Context::new(), jit_module, instance); assert!(cx.global_asm.is_empty()); jit_module.finalize_definitions().unwrap(); diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 6e925cea27707..d09d3a529759c 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -17,7 +17,7 @@ fn predefine_mono_items<'tcx>( module: &mut dyn Module, mono_items: &[(MonoItem<'tcx>, (RLinkage, Visibility))], ) { - tcx.sess.time("predefine functions", || { + tcx.prof.generic_activity("predefine functions").run(|| { let is_compiler_builtins = tcx.is_compiler_builtins(LOCAL_CRATE); for &(mono_item, (linkage, visibility)) in mono_items { match mono_item { @@ -39,16 +39,3 @@ fn predefine_mono_items<'tcx>( } }); } - -fn time(tcx: TyCtxt<'_>, display: bool, name: &'static str, f: impl FnOnce() -> R) -> R { - if display { - println!("[{:<30}: {}] start", tcx.crate_name(LOCAL_CRATE), name); - let before = std::time::Instant::now(); - let res = tcx.sess.time(name, f); - let after = std::time::Instant::now(); - println!("[{:<30}: {}] end time: {:?}", tcx.crate_name(LOCAL_CRATE), name, after - before); - res - } else { - tcx.sess.time(name, f) - } -} diff --git a/src/global_asm.rs b/src/global_asm.rs index dcbcaba30feed..46c78ce6a1e34 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -7,7 +7,7 @@ use std::process::{Command, Stdio}; use std::sync::Arc; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; -use rustc_hir::ItemId; +use rustc_hir::{InlineAsmOperand, ItemId}; use rustc_session::config::{OutputFilenames, OutputType}; use crate::prelude::*; @@ -23,7 +23,46 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, for piece in asm.template { match *piece { InlineAsmTemplatePiece::String(ref s) => global_asm.push_str(s), - InlineAsmTemplatePiece::Placeholder { .. } => todo!(), + InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: op_sp } => { + match asm.operands[operand_idx].0 { + InlineAsmOperand::Const { ref anon_const } => { + let const_value = + tcx.const_eval_poly(anon_const.def_id.to_def_id()).unwrap_or_else( + |_| span_bug!(op_sp, "asm const cannot be resolved"), + ); + let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + let string = rustc_codegen_ssa::common::asm_const_to_str( + tcx, + op_sp, + const_value, + RevealAllLayoutCx(tcx).layout_of(ty), + ); + global_asm.push_str(&string); + } + InlineAsmOperand::SymFn { anon_const } => { + let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + let instance = match ty.kind() { + &ty::FnDef(def_id, substs) => Instance::new(def_id, substs), + _ => span_bug!(op_sp, "asm sym is not a function"), + }; + let symbol = tcx.symbol_name(instance); + // FIXME handle the case where the function was made private to the + // current codegen unit + global_asm.push_str(symbol.name); + } + InlineAsmOperand::SymStatic { path: _, def_id } => { + let instance = Instance::mono(tcx, def_id).polymorphize(tcx); + let symbol = tcx.symbol_name(instance); + global_asm.push_str(symbol.name); + } + InlineAsmOperand::In { .. } + | InlineAsmOperand::Out { .. } + | InlineAsmOperand::InOut { .. } + | InlineAsmOperand::SplitInOut { .. } => { + span_bug!(op_sp, "invalid operand type for global_asm!") + } + } + } } } global_asm.push_str("\n.att_syntax\n\n"); diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 3fcc84d39295f..6206fbf7dd571 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -9,9 +9,33 @@ use rustc_middle::mir::InlineAsmOperand; use rustc_span::sym; use rustc_target::asm::*; +enum CInlineAsmOperand<'tcx> { + In { + reg: InlineAsmRegOrRegClass, + value: CValue<'tcx>, + }, + Out { + reg: InlineAsmRegOrRegClass, + late: bool, + place: Option>, + }, + InOut { + reg: InlineAsmRegOrRegClass, + _late: bool, + in_value: CValue<'tcx>, + out_place: Option>, + }, + Const { + value: String, + }, + Symbol { + symbol: String, + }, +} + pub(crate) fn codegen_inline_asm<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - _span: Span, + span: Span, template: &[InlineAsmTemplatePiece], operands: &[InlineAsmOperand<'tcx>], options: InlineAsmOptions, @@ -198,6 +222,81 @@ pub(crate) fn codegen_inline_asm<'tcx>( } } + let operands = operands + .into_iter() + .map(|operand| match *operand { + InlineAsmOperand::In { reg, ref value } => { + CInlineAsmOperand::In { reg, value: crate::base::codegen_operand(fx, value) } + } + InlineAsmOperand::Out { reg, late, ref place } => CInlineAsmOperand::Out { + reg, + late, + place: place.map(|place| crate::base::codegen_place(fx, place)), + }, + InlineAsmOperand::InOut { reg, late, ref in_value, ref out_place } => { + CInlineAsmOperand::InOut { + reg, + _late: late, + in_value: crate::base::codegen_operand(fx, in_value), + out_place: out_place.map(|place| crate::base::codegen_place(fx, place)), + } + } + InlineAsmOperand::Const { ref value } => { + let (const_value, ty) = crate::constant::eval_mir_constant(fx, &*value) + .unwrap_or_else(|| span_bug!(span, "asm const cannot be resolved")); + let value = rustc_codegen_ssa::common::asm_const_to_str( + fx.tcx, + span, + const_value, + fx.layout_of(ty), + ); + CInlineAsmOperand::Const { value } + } + InlineAsmOperand::SymFn { ref value } => { + let literal = fx.monomorphize(value.literal); + if let ty::FnDef(def_id, substs) = *literal.ty().kind() { + let instance = ty::Instance::resolve_for_fn_ptr( + fx.tcx, + ty::ParamEnv::reveal_all(), + def_id, + substs, + ) + .unwrap(); + let symbol = fx.tcx.symbol_name(instance); + + // Pass a wrapper rather than the function itself as the function itself may not + // be exported from the main codegen unit and may thus be unreachable from the + // object file created by an external assembler. + let inline_asm_index = fx.cx.inline_asm_index.get(); + fx.cx.inline_asm_index.set(inline_asm_index + 1); + let wrapper_name = format!( + "__inline_asm_{}_wrapper_n{}", + fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + inline_asm_index + ); + let sig = + get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance); + create_wrapper_function( + fx.module, + &mut fx.cx.unwind_context, + sig, + &wrapper_name, + symbol.name, + ); + + CInlineAsmOperand::Symbol { symbol: wrapper_name } + } else { + span_bug!(span, "invalid type for asm sym (fn)"); + } + } + InlineAsmOperand::SymStatic { def_id } => { + assert!(fx.tcx.is_static(def_id)); + let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); + CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() } + } + }) + .collect::>(); + let mut inputs = Vec::new(); let mut outputs = Vec::new(); @@ -206,7 +305,7 @@ pub(crate) fn codegen_inline_asm<'tcx>( arch: fx.tcx.sess.asm_arch.unwrap(), enclosing_def_id: fx.instance.def_id(), template, - operands, + operands: &operands, options, registers: Vec::new(), stack_slots_clobber: Vec::new(), @@ -229,36 +328,22 @@ pub(crate) fn codegen_inline_asm<'tcx>( fx.cx.global_asm.push_str(&generated_asm); for (i, operand) in operands.iter().enumerate() { - match *operand { - InlineAsmOperand::In { reg: _, ref value } => { - inputs.push(( - asm_gen.stack_slots_input[i].unwrap(), - crate::base::codegen_operand(fx, value).load_scalar(fx), - )); - } - InlineAsmOperand::Out { reg: _, late: _, place } => { + match operand { + CInlineAsmOperand::In { reg: _, value } => { + inputs.push((asm_gen.stack_slots_input[i].unwrap(), value.load_scalar(fx))); + } + CInlineAsmOperand::Out { reg: _, late: _, place } => { if let Some(place) = place { - outputs.push(( - asm_gen.stack_slots_output[i].unwrap(), - crate::base::codegen_place(fx, place), - )); + outputs.push((asm_gen.stack_slots_output[i].unwrap(), place.clone())); } } - InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => { - inputs.push(( - asm_gen.stack_slots_input[i].unwrap(), - crate::base::codegen_operand(fx, in_value).load_scalar(fx), - )); + CInlineAsmOperand::InOut { reg: _, _late: _, in_value, out_place } => { + inputs.push((asm_gen.stack_slots_input[i].unwrap(), in_value.load_scalar(fx))); if let Some(out_place) = out_place { - outputs.push(( - asm_gen.stack_slots_output[i].unwrap(), - crate::base::codegen_place(fx, out_place), - )); + outputs.push((asm_gen.stack_slots_output[i].unwrap(), out_place.clone())); } } - InlineAsmOperand::Const { value: _ } => todo!(), - InlineAsmOperand::SymFn { value: _ } => todo!(), - InlineAsmOperand::SymStatic { def_id: _ } => todo!(), + CInlineAsmOperand::Const { value: _ } | CInlineAsmOperand::Symbol { symbol: _ } => {} } } @@ -280,7 +365,7 @@ struct InlineAssemblyGenerator<'a, 'tcx> { arch: InlineAsmArch, enclosing_def_id: DefId, template: &'a [InlineAsmTemplatePiece], - operands: &'a [InlineAsmOperand<'tcx>], + operands: &'a [CInlineAsmOperand<'tcx>], options: InlineAsmOptions, registers: Vec>, stack_slots_clobber: Vec>, @@ -304,18 +389,20 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { // Add explicit registers to the allocated set. for (i, operand) in self.operands.iter().enumerate() { match *operand { - InlineAsmOperand::In { reg: InlineAsmRegOrRegClass::Reg(reg), .. } => { + CInlineAsmOperand::In { reg: InlineAsmRegOrRegClass::Reg(reg), .. } => { regs[i] = Some(reg); allocated.entry(reg).or_default().0 = true; } - InlineAsmOperand::Out { - reg: InlineAsmRegOrRegClass::Reg(reg), late: true, .. + CInlineAsmOperand::Out { + reg: InlineAsmRegOrRegClass::Reg(reg), + late: true, + .. } => { regs[i] = Some(reg); allocated.entry(reg).or_default().1 = true; } - InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(reg), .. } - | InlineAsmOperand::InOut { reg: InlineAsmRegOrRegClass::Reg(reg), .. } => { + CInlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(reg), .. } + | CInlineAsmOperand::InOut { reg: InlineAsmRegOrRegClass::Reg(reg), .. } => { regs[i] = Some(reg); allocated.insert(reg, (true, true)); } @@ -326,12 +413,12 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { // Allocate out/inout/inlateout registers first because they are more constrained. for (i, operand) in self.operands.iter().enumerate() { match *operand { - InlineAsmOperand::Out { + CInlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::RegClass(class), late: false, .. } - | InlineAsmOperand::InOut { + | CInlineAsmOperand::InOut { reg: InlineAsmRegOrRegClass::RegClass(class), .. } => { let mut alloc_reg = None; @@ -360,7 +447,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { // Allocate in/lateout. for (i, operand) in self.operands.iter().enumerate() { match *operand { - InlineAsmOperand::In { reg: InlineAsmRegOrRegClass::RegClass(class), .. } => { + CInlineAsmOperand::In { reg: InlineAsmRegOrRegClass::RegClass(class), .. } => { let mut alloc_reg = None; for ® in &map[&class] { let mut used = false; @@ -380,7 +467,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { regs[i] = Some(reg); allocated.entry(reg).or_default().0 = true; } - InlineAsmOperand::Out { + CInlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::RegClass(class), late: true, .. @@ -455,7 +542,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { // Allocate stack slots for inout for (i, operand) in self.operands.iter().enumerate() { match *operand { - InlineAsmOperand::InOut { reg, out_place: Some(_), .. } => { + CInlineAsmOperand::InOut { reg, out_place: Some(_), .. } => { let slot = new_slot(reg.reg_class()); slots_input[i] = Some(slot); slots_output[i] = Some(slot); @@ -470,8 +557,8 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { // Allocate stack slots for input for (i, operand) in self.operands.iter().enumerate() { match *operand { - InlineAsmOperand::In { reg, .. } - | InlineAsmOperand::InOut { reg, out_place: None, .. } => { + CInlineAsmOperand::In { reg, .. } + | CInlineAsmOperand::InOut { reg, out_place: None, .. } => { slots_input[i] = Some(new_slot(reg.reg_class())); } _ => (), @@ -487,7 +574,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { // Allocate stack slots for output for (i, operand) in self.operands.iter().enumerate() { match *operand { - InlineAsmOperand::Out { reg, place: Some(_), .. } => { + CInlineAsmOperand::Out { reg, place: Some(_), .. } => { slots_output[i] = Some(new_slot(reg.reg_class())); } _ => (), @@ -549,13 +636,23 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { generated_asm.push_str(s); } InlineAsmTemplatePiece::Placeholder { operand_idx, modifier, span: _ } => { - if self.options.contains(InlineAsmOptions::ATT_SYNTAX) { - generated_asm.push('%'); + match self.operands[*operand_idx] { + CInlineAsmOperand::In { .. } + | CInlineAsmOperand::Out { .. } + | CInlineAsmOperand::InOut { .. } => { + if self.options.contains(InlineAsmOptions::ATT_SYNTAX) { + generated_asm.push('%'); + } + self.registers[*operand_idx] + .unwrap() + .emit(&mut generated_asm, self.arch, *modifier) + .unwrap(); + } + CInlineAsmOperand::Const { ref value } => { + generated_asm.push_str(value); + } + CInlineAsmOperand::Symbol { ref symbol } => generated_asm.push_str(symbol), } - self.registers[*operand_idx] - .unwrap() - .emit(&mut generated_asm, self.arch, *modifier) - .unwrap(); } } } diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index d561cf139b6c9..892e7c30e2f7a 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -218,22 +218,6 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( let intrinsic = fx.tcx.item_name(instance.def_id()); let substs = instance.substs; - let target = if let Some(target) = target { - target - } else { - // Insert non returning intrinsics here - match intrinsic { - sym::abort => { - fx.bcx.ins().trap(TrapCode::User(0)); - } - sym::transmute => { - crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", source_info); - } - _ => unimplemented!("unsupported intrinsic {}", intrinsic), - } - return; - }; - if intrinsic.as_str().starts_with("simd_") { self::simd::codegen_simd_intrinsic_call( fx, @@ -241,11 +225,11 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( substs, args, destination, - target, + target.expect("target for simd intrinsic"), source_info.span, ); } else if codegen_float_intrinsic_call(fx, intrinsic, args, destination) { - let ret_block = fx.get_block(target); + let ret_block = fx.get_block(target.expect("target for float intrinsic")); fx.bcx.ins().jump(ret_block, &[]); } else { codegen_regular_intrinsic_call( @@ -255,7 +239,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( substs, args, destination, - Some(target), + target, source_info, ); } @@ -382,6 +366,10 @@ fn codegen_regular_intrinsic_call<'tcx>( let usize_layout = fx.layout_of(fx.tcx.types.usize); match intrinsic { + sym::abort => { + fx.bcx.ins().trap(TrapCode::User(0)); + return; + } sym::likely | sym::unlikely => { intrinsic_args!(fx, args => (a); intrinsic); @@ -579,6 +567,11 @@ fn codegen_regular_intrinsic_call<'tcx>( sym::transmute => { intrinsic_args!(fx, args => (from); intrinsic); + if ret.layout().abi.is_uninhabited() { + crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", source_info); + return; + } + ret.write_cvalue_transmute(fx, from); } sym::write_bytes | sym::volatile_set_memory => { diff --git a/src/value_and_place.rs b/src/value_and_place.rs index fa06d6c3ba7f3..320eecaee008e 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -588,10 +588,13 @@ impl<'tcx> CPlace<'tcx> { return; } CPlaceInner::VarPair(_local, var1, var2) => { - let (ptr, meta) = from.force_stack(fx); - assert!(meta.is_none()); - let (data1, data2) = - CValue(CValueInner::ByRef(ptr, None), dst_layout).load_scalar_pair(fx); + let (data1, data2) = if from.layout().ty == dst_layout.ty { + CValue(from.0, dst_layout).load_scalar_pair(fx) + } else { + let (ptr, meta) = from.force_stack(fx); + assert!(meta.is_none()); + CValue(CValueInner::ByRef(ptr, None), dst_layout).load_scalar_pair(fx) + }; let (dst_ty1, dst_ty2) = fx.clif_pair_type(self.layout().ty).unwrap(); transmute_value(fx, var1, data1, dst_ty1); transmute_value(fx, var2, data2, dst_ty2); From bdb066547945f0eaa9bec579ace72279866d8c0d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Feb 2023 10:35:52 +0000 Subject: [PATCH 004/124] Avoid spurious visible_parent_map query invocation --- src/intrinsics/mod.rs | 68 +++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 41 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 892e7c30e2f7a..b92a8ee0ec129 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -22,7 +22,7 @@ pub(crate) use cpuid::codegen_cpuid_call; pub(crate) use llvm::codegen_llvm_intrinsic_call; use rustc_middle::ty::layout::HasParamEnv; -use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::subst::SubstsRef; use rustc_span::symbol::{kw, sym, Symbol}; @@ -640,47 +640,33 @@ fn codegen_regular_intrinsic_call<'tcx>( sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => { intrinsic_args!(fx, args => (); intrinsic); - let layout = fx.layout_of(substs.type_at(0)); - if layout.abi.is_uninhabited() { - with_no_trimmed_paths!({ - crate::base::codegen_panic_nounwind( - fx, - &format!("attempted to instantiate uninhabited type `{}`", layout.ty), - source_info, - ) - }); - return; - } - - if intrinsic == sym::assert_zero_valid - && !fx.tcx.permits_zero_init(fx.param_env().and(layout)) - { - with_no_trimmed_paths!({ - crate::base::codegen_panic_nounwind( - fx, - &format!( - "attempted to zero-initialize type `{}`, which is invalid", - layout.ty - ), - source_info, - ); - }); - return; - } - - if intrinsic == sym::assert_mem_uninitialized_valid - && !fx.tcx.permits_uninit_init(fx.param_env().and(layout)) - { - with_no_trimmed_paths!({ - crate::base::codegen_panic_nounwind( - fx, - &format!( - "attempted to leave type `{}` uninitialized, which is invalid", - layout.ty - ), - source_info, - ) + let ty = substs.type_at(0); + let layout = fx.layout_of(ty); + let do_panic = match intrinsic { + sym::assert_inhabited => layout.abi.is_uninhabited(), + sym::assert_zero_valid => !fx.tcx.permits_zero_init(fx.param_env().and(layout)), + sym::assert_mem_uninitialized_valid => { + !fx.tcx.permits_uninit_init(fx.param_env().and(layout)) + } + _ => unreachable!(), + }; + if do_panic { + let msg_str = with_no_visible_paths!({ + with_no_trimmed_paths!({ + if layout.abi.is_uninhabited() { + // Use this error even for the other intrinsics as it is more precise. + format!("attempted to instantiate uninhabited type `{}`", ty) + } else if intrinsic == sym::assert_zero_valid { + format!("attempted to zero-initialize type `{}`, which is invalid", ty) + } else { + format!( + "attempted to leave type `{}` uninitialized, which is invalid", + ty + ) + } + }) }); + crate::base::codegen_panic_nounwind(fx, &msg_str, source_info); return; } } From 7870b296e45a3758ee3f8577303b24128695694f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Feb 2023 11:16:07 +0000 Subject: [PATCH 005/124] Remove a couple of duplicate layout_of and monomorphize calls --- src/abi/mod.rs | 8 +++----- src/abi/returning.rs | 3 ++- src/analyze.rs | 30 +++++++++++------------------- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 3c34585d4191e..7b9f3e6761ac9 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -275,10 +275,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ self::comments::add_locals_header_comment(fx); for (local, arg_kind, ty) in func_params { - let layout = fx.layout_of(ty); - - let is_ssa = ssa_analyzed[local] == crate::analyze::SsaKind::Ssa; - // While this is normally an optimization to prevent an unnecessary copy when an argument is // not mutated by the current function, this is necessary to support unsized arguments. if let ArgKind::Normal(Some(val)) = arg_kind { @@ -300,6 +296,8 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ } } + let layout = fx.layout_of(ty); + let is_ssa = ssa_analyzed[local].is_ssa(fx, ty); let place = make_local_place(fx, local, layout, is_ssa); assert_eq!(fx.local_map.push(place), local); @@ -323,7 +321,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ let ty = fx.monomorphize(fx.mir.local_decls[local].ty); let layout = fx.layout_of(ty); - let is_ssa = ssa_analyzed[local] == crate::analyze::SsaKind::Ssa; + let is_ssa = ssa_analyzed[local].is_ssa(fx, ty); let place = make_local_place(fx, local, layout, is_ssa); assert_eq!(fx.local_map.push(place), local); diff --git a/src/abi/returning.rs b/src/abi/returning.rs index aaa1418767a35..6d3e8eda276a4 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -14,7 +14,8 @@ pub(super) fn codegen_return_param<'tcx>( ) -> CPlace<'tcx> { let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode { PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(..) => { - let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa; + let is_ssa = + ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.as_ref().unwrap().ret.layout.ty); ( super::make_local_place( fx, diff --git a/src/analyze.rs b/src/analyze.rs index 0cbb9f3ec2d80..54d5c1c2ae9e9 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -4,34 +4,30 @@ use crate::prelude::*; use rustc_index::vec::IndexVec; use rustc_middle::mir::StatementKind::*; +use rustc_middle::ty::Ty; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub(crate) enum SsaKind { NotSsa, - Ssa, + MaybeSsa, +} + +impl SsaKind { + pub(crate) fn is_ssa<'tcx>(self, fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool { + self == SsaKind::MaybeSsa && (fx.clif_type(ty).is_some() || fx.clif_pair_type(ty).is_some()) + } } pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec { - let mut flag_map = fx - .mir - .local_decls - .iter() - .map(|local_decl| { - let ty = fx.monomorphize(local_decl.ty); - if fx.clif_type(ty).is_some() || fx.clif_pair_type(ty).is_some() { - SsaKind::Ssa - } else { - SsaKind::NotSsa - } - }) - .collect::>(); + let mut flag_map = + fx.mir.local_decls.iter().map(|_| SsaKind::MaybeSsa).collect::>(); for bb in fx.mir.basic_blocks.iter() { for stmt in bb.statements.iter() { match &stmt.kind { Assign(place_and_rval) => match &place_and_rval.1 { Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => { - not_ssa(&mut flag_map, place.local) + flag_map[place.local] = SsaKind::NotSsa; } _ => {} }, @@ -42,7 +38,3 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec { flag_map } - -fn not_ssa(flag_map: &mut IndexVec, local: Local) { - flag_map[local] = SsaKind::NotSsa; -} From 4a1c2d9c7c5cb370eea0df964d537b60d29a4191 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:08:39 +0000 Subject: [PATCH 006/124] Fix signaling available_token_condvar when a new token is received MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This slightly improves performance on systems with many cores and barely affects systems with few cores. My laptop (2 core + HT): Before: Benchmark 2: RUSTC=rustc /home/bjorn/Projects/cg_clif2/./dist/cargo-clif build --manifest-path /home/bjorn/Projects/cg_clif2/./download/simple-raytracer/Cargo.toml --target-dir /home/bjorn/Projects/cg_clif2/./build/simple_raytracer Time (mean ± σ): 12.042 s ± 0.313 s [User: 29.434 s, System: 4.720 s] Range (min … max): 11.670 s … 12.795 s 10 runs After: Benchmark 2: RUSTC=rustc /home/bjorn/Projects/cg_clif2/./dist/cargo-clif build --manifest-path /home/bjorn/Projects/cg_clif2/./download/simple-raytracer/Cargo.toml --target-dir /home/bjorn/Projects/cg_clif2/./build/simple_raytracer Time (mean ± σ): 12.037 s ± 0.384 s [User: 29.960 s, System: 4.722 s] Range (min … max): 11.673 s … 12.769 s 10 runs Dev desktop (32 cores) Before: Benchmark 2: RUSTC=rustc /home/gh-bjorn3/cg_clif/./dist/cargo-clif build --manifest-path /home/gh-bjorn3/cg_clif/./download/simple-raytracer/Cargo.toml --target-dir /home/gh-bjorn3/cg_clif/./build/simple_raytracer Time (mean ± σ): 10.425 s ± 0.104 s [User: 25.877 s, System: 5.513 s] Range (min … max): 10.267 s … 10.640 s 10 runs After: Benchmark 2: RUSTC=rustc /home/gh-bjorn3/cg_clif/./dist/cargo-clif build --manifest-path /home/gh-bjorn3/cg_clif/./download/simple-raytracer/Cargo.toml --target-dir /home/gh-bjorn3/cg_clif/./build/simple_raytracer Time (mean ± σ): 10.212 s ± 0.100 s [User: 25.918 s, System: 5.555 s] Range (min … max): 10.079 s … 10.362 s 10 runs --- src/concurrency_limiter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/concurrency_limiter.rs b/src/concurrency_limiter.rs index f855e20e0a1a3..203219a8a754a 100644 --- a/src/concurrency_limiter.rs +++ b/src/concurrency_limiter.rs @@ -32,7 +32,7 @@ impl ConcurrencyLimiter { ConcurrencyLimiter { helper_thread: Some(helper_thread), state, - available_token_condvar: Arc::new(Condvar::new()), + available_token_condvar, finished: false, } } From 1a072c5688e3bb8f6ba7db5bce3ca1c29cf3919d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 10 Feb 2023 18:40:09 +0100 Subject: [PATCH 007/124] clippy::perf fixes --- src/base.rs | 2 +- src/global_asm.rs | 2 +- src/pretty_clif.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index 189d952a92f17..c084d10502a9d 100644 --- a/src/base.rs +++ b/src/base.rs @@ -192,7 +192,7 @@ pub(crate) fn compile_fn( let pass_times = cranelift_codegen::timing::take_current(); // Replace newlines with | as measureme doesn't allow control characters like // newlines inside strings. - recorder.record_arg(format!("{}", pass_times).replace("\n", " | ")); + recorder.record_arg(format!("{}", pass_times).replace('\n', " | ")); recording_args = true; }, ) diff --git a/src/global_asm.rs b/src/global_asm.rs index 46c78ce6a1e34..a74f8ffa23d43 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -125,7 +125,7 @@ pub(crate) fn compile_global_asm( let output_object_file = config.output_filenames.temp_path(OutputType::Object, Some(cgu_name)); // Assemble `global_asm` - let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm"); + let global_asm_object_file = add_file_stem_postfix(output_object_file, ".asm"); let mut child = Command::new(&config.assembler) .arg("-o") .arg(&global_asm_object_file) diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index a7af162687c34..e0a081c9d498b 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -245,7 +245,7 @@ pub(crate) fn write_clif_file( for flag in isa.flags().iter() { writeln!(file, "set {}", flag)?; } - write!(file, "target {}", isa.triple().architecture.to_string())?; + write!(file, "target {}", isa.triple().architecture)?; for isa_flag in isa.isa_flags().iter() { write!(file, " {}", isa_flag)?; } From 0b62b643e388012a2333d62b51c881adce289c5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 10 Feb 2023 18:47:08 +0100 Subject: [PATCH 008/124] clippy::complexity fixes --- src/abi/mod.rs | 7 +++---- src/base.rs | 2 +- src/common.rs | 2 +- src/constant.rs | 4 ++-- src/debuginfo/emit.rs | 2 +- src/driver/aot.rs | 4 ++-- src/inline_asm.rs | 6 +++--- src/main_shim.rs | 2 +- src/unsize.rs | 2 +- 9 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 7b9f3e6761ac9..3eed2e4a11e3a 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -25,7 +25,7 @@ fn clif_sig_from_fn_abi<'tcx>( ) -> Signature { let call_conv = conv_to_call_conv(tcx.sess, fn_abi.conv, default_call_conv); - let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten(); + let inputs = fn_abi.args.iter().flat_map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()); let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx); // Sometimes the first param is an pointer to the place where the return value needs to be stored. @@ -513,10 +513,9 @@ pub(crate) fn codegen_terminator_call<'tcx>( args.into_iter() .enumerate() .skip(if first_arg_override.is_some() { 1 } else { 0 }) - .map(|(i, arg)| { + .flat_map(|(i, arg)| { adjust_arg_for_abi(fx, arg.value, &fn_abi.args[i], arg.is_owned).into_iter() - }) - .flatten(), + }), ) .collect::>(); diff --git a/src/base.rs b/src/base.rs index c084d10502a9d..7ad242949000d 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1000,7 +1000,7 @@ fn codegen_panic_inner<'tcx>( let symbol_name = fx.tcx.symbol_name(instance).name; fx.lib_call( - &*symbol_name, + symbol_name, args.iter().map(|&arg| AbiParam::new(fx.bcx.func.dfg.value_type(arg))).collect(), vec![], args, diff --git a/src/common.rs b/src/common.rs index a8be0d32cc8c7..0615c06c0fe34 100644 --- a/src/common.rs +++ b/src/common.rs @@ -75,7 +75,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { let (element, count) = match &tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().abi { - Abi::Vector { element, count } => (element.clone(), *count), + Abi::Vector { element, count } => (*element, *count), _ => unreachable!(), }; diff --git a/src/constant.rs b/src/constant.rs index 49c4f1aaaefc6..04e0897dad516 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -290,7 +290,7 @@ fn data_id_for_static( }; let data_id = match module.declare_data( - &*symbol_name, + symbol_name, linkage, is_mutable, attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL), @@ -338,7 +338,7 @@ fn data_id_for_static( }; let data_id = match module.declare_data( - &*symbol_name, + symbol_name, linkage, is_mutable, attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL), diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index 9583cd2ec60f8..c4a5627e662f1 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -113,7 +113,7 @@ impl Writer for WriterRelocate { offset: offset as u32, size, name: DebugRelocName::Symbol(symbol), - addend: addend as i64, + addend, kind: object::RelocationKind::Absolute, }); self.write_udata(0, size) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 58b01dfb5b0ec..6f96cb00df0fc 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -381,7 +381,7 @@ pub(crate) fn run_aot( }; if tcx.dep_graph.is_fully_enabled() { - for cgu in &*cgus { + for cgu in cgus { tcx.ensure().codegen_unit(cgu.name()); } } @@ -421,7 +421,7 @@ pub(crate) fn run_aot( CguReuse::PreLto => unreachable!(), CguReuse::PostLto => { concurrency_limiter.job_already_done(); - OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, &*cgu)) + OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) } } }) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 6206fbf7dd571..3ba530c040f7f 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -242,7 +242,7 @@ pub(crate) fn codegen_inline_asm<'tcx>( } } InlineAsmOperand::Const { ref value } => { - let (const_value, ty) = crate::constant::eval_mir_constant(fx, &*value) + let (const_value, ty) = crate::constant::eval_mir_constant(fx, value) .unwrap_or_else(|| span_bug!(span, "asm const cannot be resolved")); let value = rustc_codegen_ssa::common::asm_const_to_str( fx.tcx, @@ -334,13 +334,13 @@ pub(crate) fn codegen_inline_asm<'tcx>( } CInlineAsmOperand::Out { reg: _, late: _, place } => { if let Some(place) = place { - outputs.push((asm_gen.stack_slots_output[i].unwrap(), place.clone())); + outputs.push((asm_gen.stack_slots_output[i].unwrap(), *place)); } } CInlineAsmOperand::InOut { reg: _, _late: _, in_value, out_place } => { inputs.push((asm_gen.stack_slots_input[i].unwrap(), in_value.load_scalar(fx))); if let Some(out_place) = out_place { - outputs.push((asm_gen.stack_slots_output[i].unwrap(), out_place.clone())); + outputs.push((asm_gen.stack_slots_output[i].unwrap(), *out_place)); } } CInlineAsmOperand::Const { value: _ } | CInlineAsmOperand::Symbol { symbol: _ } => {} diff --git a/src/main_shim.rs b/src/main_shim.rs index 3e3b685713427..bc227df11c888 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -28,7 +28,7 @@ pub(crate) fn maybe_create_entry_wrapper( if main_def_id.is_local() { let instance = Instance::mono(tcx, main_def_id).polymorphize(tcx); - if !is_jit && module.get_name(&*tcx.symbol_name(instance).name).is_none() { + if !is_jit && module.get_name(tcx.symbol_name(instance).name).is_none() { return; } } else if !is_primary_cgu { diff --git a/src/unsize.rs b/src/unsize.rs index 9c88f7dbcda33..8c9ae9ba3b6b3 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -55,7 +55,7 @@ pub(crate) fn unsized_info<'tcx>( old_info } } - (_, &ty::Dynamic(ref data, ..)) => crate::vtable::get_vtable(fx, source, data.principal()), + (_, ty::Dynamic(data, ..)) => crate::vtable::get_vtable(fx, source, data.principal()), _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target), } } From c95eca2857ef712c8fe952c17fce8a5e962fcacc Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Thu, 9 Feb 2023 14:02:47 +0000 Subject: [PATCH 009/124] Alias folding/visiting traits instead of re-export --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index d3868730557b7..c7fe382bac4e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,7 +86,7 @@ mod prelude { pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, - TypeFoldable, TypeVisitable, UintTy, + TypeFoldable, UintTy, }; pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx}; From 14bc2e60c236d3b349142cda071cafc9ceee2d3a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 14 Feb 2023 08:51:19 +0000 Subject: [PATCH 010/124] s/eval_usize/eval_target_usize/ for clarity --- src/base.rs | 2 +- src/intrinsics/simd.rs | 4 ++-- src/unsize.rs | 2 +- src/value_and_place.rs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/base.rs b/src/base.rs index 189d952a92f17..95778de3abafc 100644 --- a/src/base.rs +++ b/src/base.rs @@ -857,7 +857,7 @@ fn codegen_stmt<'tcx>( fn codegen_array_len<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>) -> Value { match *place.layout().ty.kind() { ty::Array(_elem_ty, len) => { - let len = fx.monomorphize(len).eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64; + let len = fx.monomorphize(len).eval_target_usize(fx.tcx, ParamEnv::reveal_all()) as i64; fx.bcx.ins().iconst(fx.pointer_type, len) } ty::Slice(_elem_ty) => { diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index b33eb29754ab7..a1d63acfb6166 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -141,7 +141,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let idx_ty = fx.monomorphize(idx.ty(fx.mir, fx.tcx)); match idx_ty.kind() { ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => len - .try_eval_usize(fx.tcx, ty::ParamEnv::reveal_all()) + .try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all()) .unwrap_or_else(|| { span_bug!(span, "could not evaluate shuffle index array length") }) @@ -735,7 +735,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => {} ty::Array(elem, len) if matches!(elem.kind(), ty::Uint(ty::UintTy::U8)) - && len.try_eval_usize(fx.tcx, ty::ParamEnv::reveal_all()) + && len.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all()) == Some(expected_bytes) => {} _ => { fx.tcx.sess.span_fatal( diff --git a/src/unsize.rs b/src/unsize.rs index 9c88f7dbcda33..a0745582d6669 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -24,7 +24,7 @@ pub(crate) fn unsized_info<'tcx>( (&ty::Array(_, len), &ty::Slice(_)) => fx .bcx .ins() - .iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64), + .iconst(fx.pointer_type, len.eval_target_usize(fx.tcx, ParamEnv::reveal_all()) as i64), ( &ty::Dynamic(ref data_a, _, src_dyn_kind), &ty::Dynamic(ref data_b, _, target_dyn_kind), diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 320eecaee008e..cc1edaa97d800 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -564,8 +564,8 @@ impl<'tcx> CPlace<'tcx> { CPlaceInner::Var(_local, var) => { if let ty::Array(element, len) = dst_layout.ty.kind() { // Can only happen for vector types - let len = - u32::try_from(len.eval_usize(fx.tcx, ParamEnv::reveal_all())).unwrap(); + let len = u32::try_from(len.eval_target_usize(fx.tcx, ParamEnv::reveal_all())) + .unwrap(); let vector_ty = fx.clif_type(*element).unwrap().by(len).unwrap(); let data = match from.0 { From 478bc5ba01a02d3d0c0ec1b1766f15448b29b8fa Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 14 Feb 2023 12:18:14 +0100 Subject: [PATCH 011/124] Rustup to rustc 1.69.0-nightly (065852def 2023-02-13) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 40fb54b915992..a1582ee7a4618 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-06" +channel = "nightly-2023-02-14" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 5bf5153d0051d05d9f5e85f76327cb70a2666049 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 14 Feb 2023 15:49:32 +0000 Subject: [PATCH 012/124] Fix non-dynamic indexing into vector types --- src/value_and_place.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 320eecaee008e..4600d417fa1eb 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -3,6 +3,7 @@ use crate::prelude::*; use cranelift_codegen::ir::immediates::Offset32; +use cranelift_codegen::ir::{InstructionData, Opcode}; fn codegen_field<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, @@ -457,6 +458,7 @@ impl<'tcx> CPlace<'tcx> { } } + #[track_caller] pub(crate) fn to_ptr(self) -> Pointer { match self.to_ptr_maybe_unsized() { (ptr, None) => ptr, @@ -464,6 +466,7 @@ impl<'tcx> CPlace<'tcx> { } } + #[track_caller] pub(crate) fn to_ptr_maybe_unsized(self) -> (Pointer, Option) { match self.inner { CPlaceInner::Addr(ptr, extra) => (ptr, extra), @@ -787,7 +790,36 @@ impl<'tcx> CPlace<'tcx> { index: Value, ) -> CPlace<'tcx> { let (elem_layout, ptr) = match self.layout().ty.kind() { - ty::Array(elem_ty, _) => (fx.layout_of(*elem_ty), self.to_ptr()), + ty::Array(elem_ty, _) => { + let elem_layout = fx.layout_of(*elem_ty); + match self.inner { + CPlaceInner::Var(local, var) => { + // This is a hack to handle `vector_val.0[1]`. It doesn't allow dynamic + // indexing. + let lane_idx = match fx.bcx.func.dfg.insts + [fx.bcx.func.dfg.value_def(index).unwrap_inst()] + { + InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => imm, + _ => bug!( + "Dynamic indexing into a vector type is not supported: {self:?}[{index}]" + ), + }; + return CPlace { + inner: CPlaceInner::VarLane( + local, + var, + lane_idx.bits().try_into().unwrap(), + ), + layout: elem_layout, + }; + } + CPlaceInner::Addr(addr, None) => (elem_layout, addr), + CPlaceInner::Addr(_, Some(_)) + | CPlaceInner::VarPair(_, _, _) + | CPlaceInner::VarLane(_, _, _) => bug!("Can't index into {self:?}"), + } + // FIXME use VarLane in case of Var with simd type + } ty::Slice(elem_ty) => (fx.layout_of(*elem_ty), self.to_ptr_maybe_unsized().0), _ => bug!("place_index({:?})", self.layout().ty), }; From c75610891d8910d350e537acea82571d21d8cf9d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 14 Feb 2023 00:59:40 +0000 Subject: [PATCH 013/124] Make permit_uninit/zero_init fallible --- src/intrinsics/mod.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 892e7c30e2f7a..0d2367c2f83d3 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -640,7 +640,8 @@ fn codegen_regular_intrinsic_call<'tcx>( sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => { intrinsic_args!(fx, args => (); intrinsic); - let layout = fx.layout_of(substs.type_at(0)); + let ty = substs.type_at(0); + let layout = fx.layout_of(ty); if layout.abi.is_uninhabited() { with_no_trimmed_paths!({ crate::base::codegen_panic_nounwind( @@ -653,7 +654,10 @@ fn codegen_regular_intrinsic_call<'tcx>( } if intrinsic == sym::assert_zero_valid - && !fx.tcx.permits_zero_init(fx.param_env().and(layout)) + && !fx + .tcx + .permits_zero_init(fx.param_env().and(ty)) + .expect("expected to have layout during codegen") { with_no_trimmed_paths!({ crate::base::codegen_panic_nounwind( @@ -669,7 +673,10 @@ fn codegen_regular_intrinsic_call<'tcx>( } if intrinsic == sym::assert_mem_uninitialized_valid - && !fx.tcx.permits_uninit_init(fx.param_env().and(layout)) + && !fx + .tcx + .permits_uninit_init(fx.param_env().and(ty)) + .expect("expected to have layout during codegen") { with_no_trimmed_paths!({ crate::base::codegen_panic_nounwind( From f58bd0e290764f31afa45147dff743a20b4d2bfe Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 15 Feb 2023 11:43:41 +0000 Subject: [PATCH 014/124] `if $c:expr { Some($r:expr) } else { None }` =>> `$c.then(|| $r)` --- src/driver/aot.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 58b01dfb5b0ec..7c6fd9f6f1ec1 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -248,17 +248,13 @@ fn reuse_workproduct_for_cgu( dwarf_object: None, bytecode: None, }, - module_global_asm: if has_global_asm { - Some(CompiledModule { - name: cgu.name().to_string(), - kind: ModuleKind::Regular, - object: Some(obj_out_global_asm), - dwarf_object: None, - bytecode: None, - }) - } else { - None - }, + module_global_asm: has_global_asm.then(|| CompiledModule { + name: cgu.name().to_string(), + kind: ModuleKind::Regular, + object: Some(obj_out_global_asm), + dwarf_object: None, + bytecode: None, + }), existing_work_product: Some((cgu.work_product_id(), work_product)), }) } From 8fe8e533009adda27754abf05af6ed623f7e9c86 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Feb 2023 11:47:50 +1100 Subject: [PATCH 015/124] Replace `mk_foo` calls with `infer_foo` where possible. There are several `mk_foo`/`intern_foo` pairs, where the former takes an iterator and the latter takes a slice. (This naming convention is bad, but that's a fix for another PR.) This commit changes several `mk_foo` occurrences into `intern_foo`, avoiding the need for some `.iter()`/`.into_iter()` calls. Affected cases: - mk_type_list - mk_tup - mk_substs - mk_const_list --- src/codegen_i128.rs | 4 ++-- src/intrinsics/llvm_x86.rs | 2 +- src/main_shim.rs | 2 +- src/num.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index 638b2d573b5dd..b4a2537b5ea93 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -56,7 +56,7 @@ pub(crate) fn maybe_codegen<'tcx>( Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) } } else { - let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); + let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32)); let lhs = lhs.load_scalar(fx); let rhs = rhs.load_scalar(fx); @@ -78,7 +78,7 @@ pub(crate) fn maybe_codegen<'tcx>( } BinOp::Add | BinOp::Sub | BinOp::Mul => { assert!(checked); - let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); + let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); let (param_types, args) = if fx.tcx.sess.target.is_like_windows { let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index d2ae6978ca2a8..cbac2e667652b 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -191,7 +191,7 @@ fn llvm_add_sub<'tcx>( // carry0 | carry1 -> carry or borrow respectively let cb_out = fx.bcx.ins().bor(cb0, cb1); - let layout = fx.layout_of(fx.tcx.mk_tup([fx.tcx.types.u8, fx.tcx.types.u64].iter())); + let layout = fx.layout_of(fx.tcx.intern_tup(&[fx.tcx.types.u8, fx.tcx.types.u64])); let val = CValue::by_val_pair(cb_out, c, layout); ret.write_cvalue(fx, val); } diff --git a/src/main_shim.rs b/src/main_shim.rs index 3e3b685713427..26327107df4c5 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper( tcx, ParamEnv::reveal_all(), report.def_id, - tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()), + tcx.intern_substs(&[GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap() diff --git a/src/num.rs b/src/num.rs index afacbec644582..05905a7bcdf30 100644 --- a/src/num.rs +++ b/src/num.rs @@ -289,7 +289,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs), }; - let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter())); + let out_layout = fx.layout_of(fx.tcx.intern_tup(&[in_lhs.layout().ty, fx.tcx.types.bool])); CValue::by_val_pair(res, has_overflow, out_layout) } From 9491031f9a4c80dbba52888666906491827c4ecb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:42:14 +0100 Subject: [PATCH 016/124] Rustup to rustc 1.69.0-nightly (0416b1a6f 2023-02-14) --- build_sysroot/Cargo.toml | 3 ++- build_system/build_sysroot.rs | 1 + ...owngrade-compiler-builtins-to-0.1.86.patch | 26 +++++++++++++++++++ rust-toolchain | 2 +- 4 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 patches/0029-sysroot-Downgrade-compiler-builtins-to-0.1.86.patch diff --git a/build_sysroot/Cargo.toml b/build_sysroot/Cargo.toml index d0e5fc4a3b9f1..cde60ce2e05a9 100644 --- a/build_sysroot/Cargo.toml +++ b/build_sysroot/Cargo.toml @@ -8,7 +8,8 @@ alloc = { path = "./sysroot_src/library/alloc" } std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] } test = { path = "./sysroot_src/library/test" } -compiler_builtins = { version = "0.1.39", default-features = false, features = ["no-asm"] } +# FIXME allow 0.1.87 and later once #1353 is fixed +compiler_builtins = { version = "=0.1.86", default-features = false, features = ["no-asm"] } [patch.crates-io] rustc-std-workspace-core = { path = "./sysroot_src/library/rustc-std-workspace-core" } diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 2e04f2c68116c..6a4d6aaa3565e 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -247,6 +247,7 @@ fn build_clif_sysroot_for_triple( if channel == "release" { build_cmd.arg("--release"); } + build_cmd.arg("--locked"); build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif"); if compiler.triple.contains("apple") { build_cmd.env("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO", "packed"); diff --git a/patches/0029-sysroot-Downgrade-compiler-builtins-to-0.1.86.patch b/patches/0029-sysroot-Downgrade-compiler-builtins-to-0.1.86.patch new file mode 100644 index 0000000000000..c5fa6aaec2bd0 --- /dev/null +++ b/patches/0029-sysroot-Downgrade-compiler-builtins-to-0.1.86.patch @@ -0,0 +1,26 @@ +From ff23f6113098987318b674088b924e22750be18c Mon Sep 17 00:00:00 2001 +From: bjorn3 <17426603+bjorn3@users.noreply.github.com> +Date: Fri, 17 Feb 2023 18:37:48 +0100 +Subject: [PATCH] Downgrade compiler-builtins to 0.1.86 + +0.1.87 doesn't work on Windows when using cg_clif +--- + library/std/Cargo.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml +index 349cd91..300f812 100644 +--- a/library/std/Cargo.toml ++++ b/library/std/Cargo.toml +@@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true } + panic_abort = { path = "../panic_abort" } + core = { path = "../core" } + libc = { version = "0.2.138", default-features = false, features = ['rustc-dep-of-std'] } +-compiler_builtins = { version = "0.1.87" } ++compiler_builtins = { version = "0.1.86" } + profiler_builtins = { path = "../profiler_builtins", optional = true } + unwind = { path = "../unwind" } + hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] } +-- +2.26.2.7.g19db9cfb68 + diff --git a/rust-toolchain b/rust-toolchain index a1582ee7a4618..eae1c2f9298a2 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-14" +channel = "nightly-2023-02-15" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 8ed6baa749dc88c8da0267839249945a28dc7338 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:28:12 +0100 Subject: [PATCH 017/124] Rustup to rustc 1.69.0-nightly (2d14db321 2023-02-15) --- build_system/build_sysroot.rs | 3 ++- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 6a4d6aaa3565e..62a025b4f8f75 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -240,7 +240,8 @@ fn build_clif_sysroot_for_triple( rustflags .push_str(&format!(" --sysroot={}", RTSTARTUP_SYSROOT.to_path(dirs).to_str().unwrap())); if channel == "release" { - rustflags.push_str(" -Zmir-opt-level=3"); + // FIXME re-enable DataflowConstProp once rust-lang/rust#108166 is fixed + rustflags.push_str(" -Zmir-opt-level=3 -Zmir-enable-passes=-DataflowConstProp"); } compiler.rustflags += &rustflags; let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs); diff --git a/rust-toolchain b/rust-toolchain index eae1c2f9298a2..02cddbac1d948 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-15" +channel = "nightly-2023-02-16" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 3c5d5bab967c2ce5e05dac7c30543a8a0c5abd43 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:55:11 +0100 Subject: [PATCH 018/124] Rustup to rustc 1.69.0-nightly (9a7cc6c32 2023-02-16) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 02cddbac1d948..96afb402476ec 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-16" +channel = "nightly-2023-02-17" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 718574a53e1262c7370106ec606c8fabe0fb6a23 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:55:51 +0100 Subject: [PATCH 019/124] Support updating to specific dates in rustup.sh Fixes #1294 --- scripts/rustup.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 34e3981b5381f..75219c82e82e0 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -2,10 +2,10 @@ set -e +TOOLCHAIN=${TOOLCHAIN:-$(date +%Y-%m-%d)} + case $1 in "prepare") - TOOLCHAIN=$(date +%Y-%m-%d) - echo "=> Installing new nightly" rustup toolchain install --profile minimal "nightly-${TOOLCHAIN}" # Sanity check to see if the nightly exists sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain @@ -42,13 +42,16 @@ case $1 in git merge sync_from_rust ;; "pull") + RUST_VERS=$(curl "https://static.rust-lang.org/dist/$TOOLCHAIN/channel-rust-nightly-git-commit-hash.txt") + echo "Pulling $RUST_VERS ($TOOLCHAIN)" + cg_clif=$(pwd) pushd ../rust - git pull origin master - rust_vers="$(git rev-parse HEAD)" + git fetch origin master + git checkout "$RUST_VERS" git subtree push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust popd - git merge sync_from_rust -m "Sync from rust $rust_vers" + git merge sync_from_rust -m "Sync from rust $RUST_VERS" git branch -d sync_from_rust ;; *) From cdf4f4287a7727b72a2f7f47a88ca1d450fdafd0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 16 Feb 2023 19:14:58 +0000 Subject: [PATCH 020/124] Remove easy_call --- src/abi/mod.rs | 32 +----------- src/cast.rs | 33 +++++-------- src/codegen_i128.rs | 18 ++++++- src/intrinsics/mod.rs | 111 ++++++++++++++++++++++-------------------- src/num.rs | 16 ++++-- src/pointer.rs | 5 -- 6 files changed, 100 insertions(+), 115 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 3eed2e4a11e3a..64bc9ab6aab41 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -125,42 +125,12 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { } let call_inst = self.bcx.ins().call(func_ref, args); if self.clif_comments.enabled() { - self.add_comment(call_inst, format!("easy_call {}", name)); + self.add_comment(call_inst, format!("lib_call {}", name)); } let results = self.bcx.inst_results(call_inst); assert!(results.len() <= 2, "{}", results.len()); results } - - pub(crate) fn easy_call( - &mut self, - name: &str, - args: &[CValue<'tcx>], - return_ty: Ty<'tcx>, - ) -> CValue<'tcx> { - let (input_tys, args): (Vec<_>, Vec<_>) = args - .iter() - .map(|arg| { - (AbiParam::new(self.clif_type(arg.layout().ty).unwrap()), arg.load_scalar(self)) - }) - .unzip(); - let return_layout = self.layout_of(return_ty); - let return_tys = if let ty::Tuple(tup) = return_ty.kind() { - tup.iter().map(|ty| AbiParam::new(self.clif_type(ty).unwrap())).collect() - } else { - vec![AbiParam::new(self.clif_type(return_ty).unwrap())] - }; - let ret_vals = self.lib_call(name, input_tys, return_tys, &args); - match *ret_vals { - [] => CValue::by_ref( - Pointer::const_addr(self, i64::from(self.pointer_type.bytes())), - return_layout, - ), - [val] => CValue::by_val(val, return_layout), - [val, extra] => CValue::by_val_pair(val, extra, return_layout), - _ => unreachable!(), - } - } } /// Make a [`CPlace`] capable of holding value of the specified type. diff --git a/src/cast.rs b/src/cast.rs index 5091c5a9fedac..8c23152cda786 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -64,17 +64,12 @@ pub(crate) fn clif_int_or_float_cast( }, ); - let from_rust_ty = if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; - - let to_rust_ty = match to_ty { - types::F32 => fx.tcx.types.f32, - types::F64 => fx.tcx.types.f64, - _ => unreachable!(), - }; - - return fx - .easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty) - .load_scalar(fx); + return fx.lib_call( + &name, + vec![AbiParam::new(types::I128)], + vec![AbiParam::new(to_ty)], + &[from], + )[0]; } // int-like -> float @@ -101,16 +96,12 @@ pub(crate) fn clif_int_or_float_cast( }, ); - let from_rust_ty = match from_ty { - types::F32 => fx.tcx.types.f32, - types::F64 => fx.tcx.types.f64, - _ => unreachable!(), - }; - - let to_rust_ty = if to_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; - - fx.easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty) - .load_scalar(fx) + fx.lib_call( + &name, + vec![AbiParam::new(from_ty)], + vec![AbiParam::new(types::I128)], + &[from], + )[0] } else if to_ty == types::I8 || to_ty == types::I16 { // FIXME implement fcvt_to_*int_sat.i8/i16 let val = if to_signed { diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index 638b2d573b5dd..af3356e8213d9 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -53,7 +53,14 @@ pub(crate) fn maybe_codegen<'tcx>( ); Some(ret_place.to_cvalue(fx)) } else { - Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) + let args: Vec<_> = vec![lhs.load_scalar(fx), rhs.load_scalar(fx)]; + let ret_val = fx.lib_call( + "__multi3", + vec![AbiParam::new(types::I128), AbiParam::new(types::I128)], + vec![AbiParam::new(types::I128)], + &args, + )[0]; + Some(CValue::by_val(ret_val, fx.layout_of(val_ty))) } } else { let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); @@ -141,7 +148,14 @@ pub(crate) fn maybe_codegen<'tcx>( ret_place.to_ptr().store(fx, ret, MemFlags::trusted()); Some(ret_place.to_cvalue(fx)) } else { - Some(fx.easy_call(name, &[lhs, rhs], lhs.layout().ty)) + let args: Vec<_> = vec![lhs.load_scalar(fx), rhs.load_scalar(fx)]; + let ret_val = fx.lib_call( + name, + vec![AbiParam::new(types::I128), AbiParam::new(types::I128)], + vec![AbiParam::new(types::I128)], + &args, + )[0]; + Some(CValue::by_val(ret_val, lhs.layout())) } } BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => { diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 34e2fe3ae45ed..b369edee8da1b 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -251,41 +251,41 @@ fn codegen_float_intrinsic_call<'tcx>( args: &[mir::Operand<'tcx>], ret: CPlace<'tcx>, ) -> bool { - let (name, arg_count, ty) = match intrinsic { - sym::expf32 => ("expf", 1, fx.tcx.types.f32), - sym::expf64 => ("exp", 1, fx.tcx.types.f64), - sym::exp2f32 => ("exp2f", 1, fx.tcx.types.f32), - sym::exp2f64 => ("exp2", 1, fx.tcx.types.f64), - sym::sqrtf32 => ("sqrtf", 1, fx.tcx.types.f32), - sym::sqrtf64 => ("sqrt", 1, fx.tcx.types.f64), - sym::powif32 => ("__powisf2", 2, fx.tcx.types.f32), // compiler-builtins - sym::powif64 => ("__powidf2", 2, fx.tcx.types.f64), // compiler-builtins - sym::powf32 => ("powf", 2, fx.tcx.types.f32), - sym::powf64 => ("pow", 2, fx.tcx.types.f64), - sym::logf32 => ("logf", 1, fx.tcx.types.f32), - sym::logf64 => ("log", 1, fx.tcx.types.f64), - sym::log2f32 => ("log2f", 1, fx.tcx.types.f32), - sym::log2f64 => ("log2", 1, fx.tcx.types.f64), - sym::log10f32 => ("log10f", 1, fx.tcx.types.f32), - sym::log10f64 => ("log10", 1, fx.tcx.types.f64), - sym::fabsf32 => ("fabsf", 1, fx.tcx.types.f32), - sym::fabsf64 => ("fabs", 1, fx.tcx.types.f64), - sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32), - sym::fmaf64 => ("fma", 3, fx.tcx.types.f64), - sym::copysignf32 => ("copysignf", 2, fx.tcx.types.f32), - sym::copysignf64 => ("copysign", 2, fx.tcx.types.f64), - sym::floorf32 => ("floorf", 1, fx.tcx.types.f32), - sym::floorf64 => ("floor", 1, fx.tcx.types.f64), - sym::ceilf32 => ("ceilf", 1, fx.tcx.types.f32), - sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64), - sym::truncf32 => ("truncf", 1, fx.tcx.types.f32), - sym::truncf64 => ("trunc", 1, fx.tcx.types.f64), - sym::roundf32 => ("roundf", 1, fx.tcx.types.f32), - sym::roundf64 => ("round", 1, fx.tcx.types.f64), - sym::sinf32 => ("sinf", 1, fx.tcx.types.f32), - sym::sinf64 => ("sin", 1, fx.tcx.types.f64), - sym::cosf32 => ("cosf", 1, fx.tcx.types.f32), - sym::cosf64 => ("cos", 1, fx.tcx.types.f64), + let (name, arg_count, ty, clif_ty) = match intrinsic { + sym::expf32 => ("expf", 1, fx.tcx.types.f32, types::F32), + sym::expf64 => ("exp", 1, fx.tcx.types.f64, types::F64), + sym::exp2f32 => ("exp2f", 1, fx.tcx.types.f32, types::F32), + sym::exp2f64 => ("exp2", 1, fx.tcx.types.f64, types::F64), + sym::sqrtf32 => ("sqrtf", 1, fx.tcx.types.f32, types::F32), + sym::sqrtf64 => ("sqrt", 1, fx.tcx.types.f64, types::F64), + sym::powif32 => ("__powisf2", 2, fx.tcx.types.f32, types::F32), // compiler-builtins + sym::powif64 => ("__powidf2", 2, fx.tcx.types.f64, types::F64), // compiler-builtins + sym::powf32 => ("powf", 2, fx.tcx.types.f32, types::F32), + sym::powf64 => ("pow", 2, fx.tcx.types.f64, types::F64), + sym::logf32 => ("logf", 1, fx.tcx.types.f32, types::F32), + sym::logf64 => ("log", 1, fx.tcx.types.f64, types::F64), + sym::log2f32 => ("log2f", 1, fx.tcx.types.f32, types::F32), + sym::log2f64 => ("log2", 1, fx.tcx.types.f64, types::F64), + sym::log10f32 => ("log10f", 1, fx.tcx.types.f32, types::F32), + sym::log10f64 => ("log10", 1, fx.tcx.types.f64, types::F64), + sym::fabsf32 => ("fabsf", 1, fx.tcx.types.f32, types::F32), + sym::fabsf64 => ("fabs", 1, fx.tcx.types.f64, types::F64), + sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), + sym::fmaf64 => ("fma", 3, fx.tcx.types.f64, types::F64), + sym::copysignf32 => ("copysignf", 2, fx.tcx.types.f32, types::F32), + sym::copysignf64 => ("copysign", 2, fx.tcx.types.f64, types::F64), + sym::floorf32 => ("floorf", 1, fx.tcx.types.f32, types::F32), + sym::floorf64 => ("floor", 1, fx.tcx.types.f64, types::F64), + sym::ceilf32 => ("ceilf", 1, fx.tcx.types.f32, types::F32), + sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64), + sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32), + sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64), + sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32), + sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64), + sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), + sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), + sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32), + sym::cosf64 => ("cos", 1, fx.tcx.types.f64, types::F64), _ => return false, }; @@ -296,15 +296,19 @@ fn codegen_float_intrinsic_call<'tcx>( let (a, b, c); let args = match args { [x] => { - a = [codegen_operand(fx, x)]; + a = [codegen_operand(fx, x).load_scalar(fx)]; &a as &[_] } [x, y] => { - b = [codegen_operand(fx, x), codegen_operand(fx, y)]; + b = [codegen_operand(fx, x).load_scalar(fx), codegen_operand(fx, y).load_scalar(fx)]; &b } [x, y, z] => { - c = [codegen_operand(fx, x), codegen_operand(fx, y), codegen_operand(fx, z)]; + c = [ + codegen_operand(fx, x).load_scalar(fx), + codegen_operand(fx, y).load_scalar(fx), + codegen_operand(fx, z).load_scalar(fx), + ]; &c } _ => unreachable!(), @@ -313,15 +317,10 @@ fn codegen_float_intrinsic_call<'tcx>( let layout = fx.layout_of(ty); let res = match intrinsic { sym::fmaf32 | sym::fmaf64 => { - let a = args[0].load_scalar(fx); - let b = args[1].load_scalar(fx); - let c = args[2].load_scalar(fx); - CValue::by_val(fx.bcx.ins().fma(a, b, c), layout) + CValue::by_val(fx.bcx.ins().fma(args[0], args[1], args[2]), layout) } sym::copysignf32 | sym::copysignf64 => { - let a = args[0].load_scalar(fx); - let b = args[1].load_scalar(fx); - CValue::by_val(fx.bcx.ins().fcopysign(a, b), layout) + CValue::by_val(fx.bcx.ins().fcopysign(args[0], args[1]), layout) } sym::fabsf32 | sym::fabsf64 @@ -331,21 +330,29 @@ fn codegen_float_intrinsic_call<'tcx>( | sym::ceilf64 | sym::truncf32 | sym::truncf64 => { - let a = args[0].load_scalar(fx); - let val = match intrinsic { - sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(a), - sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(a), - sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(a), - sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(a), + sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(args[0]), + sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), + sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), + sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), _ => unreachable!(), }; CValue::by_val(val, layout) } + // These intrinsics aren't supported natively by Cranelift. // Lower them to a libcall. - _ => fx.easy_call(name, &args, ty), + sym::powif32 | sym::powif64 => { + let input_tys: Vec<_> = vec![AbiParam::new(clif_ty), AbiParam::new(types::I32)]; + let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0]; + CValue::by_val(ret_val, fx.layout_of(ty)) + } + _ => { + let input_tys: Vec<_> = args.iter().map(|_| AbiParam::new(clif_ty)).collect(); + let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0]; + CValue::by_val(ret_val, fx.layout_of(ty)) + } }; ret.write_cvalue(fx, res); diff --git a/src/num.rs b/src/num.rs index afacbec644582..51e79f85e0257 100644 --- a/src/num.rs +++ b/src/num.rs @@ -347,12 +347,20 @@ pub(crate) fn codegen_float_binop<'tcx>( BinOp::Mul => b.fmul(lhs, rhs), BinOp::Div => b.fdiv(lhs, rhs), BinOp::Rem => { - let name = match in_lhs.layout().ty.kind() { - ty::Float(FloatTy::F32) => "fmodf", - ty::Float(FloatTy::F64) => "fmod", + let (name, ty) = match in_lhs.layout().ty.kind() { + ty::Float(FloatTy::F32) => ("fmodf", types::F32), + ty::Float(FloatTy::F64) => ("fmod", types::F64), _ => bug!(), }; - return fx.easy_call(name, &[in_lhs, in_rhs], in_lhs.layout().ty); + + let ret_val = fx.lib_call( + name, + vec![AbiParam::new(ty), AbiParam::new(ty)], + vec![AbiParam::new(ty)], + &[lhs, rhs], + )[0]; + + return CValue::by_val(ret_val, in_lhs.layout()); } BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => { let fltcc = match bin_op { diff --git a/src/pointer.rs b/src/pointer.rs index 31d827f83bfab..b60e56720ed5e 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -30,11 +30,6 @@ impl Pointer { Pointer { base: PointerBase::Stack(stack_slot), offset: Offset32::new(0) } } - pub(crate) fn const_addr(fx: &mut FunctionCx<'_, '_, '_>, addr: i64) -> Self { - let addr = fx.bcx.ins().iconst(fx.pointer_type, addr); - Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) } - } - pub(crate) fn dangling(align: Align) -> Self { Pointer { base: PointerBase::Dangling(align), offset: Offset32::new(0) } } From e58bb2acbd3a2c61d4c492c322e9c53ed3068489 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:58:05 +0000 Subject: [PATCH 021/124] Use new abi for 128bit int to float cast intrinsics on Windows --- src/cast.rs | 28 ++++++++++++++++++++++------ src/lib.rs | 2 +- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/cast.rs b/src/cast.rs index 8c23152cda786..0ab29f335a0fb 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -64,12 +64,28 @@ pub(crate) fn clif_int_or_float_cast( }, ); - return fx.lib_call( - &name, - vec![AbiParam::new(types::I128)], - vec![AbiParam::new(to_ty)], - &[from], - )[0]; + if fx.tcx.sess.target.is_like_windows { + let arg_place = CPlace::new_stack_slot( + fx, + fx.layout_of(if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }), + ); + let arg_ptr = arg_place.to_ptr(); + arg_ptr.store(fx, from, MemFlags::trusted()); + let args = [arg_ptr.get_addr(fx)]; + return fx.lib_call( + &name, + vec![AbiParam::new(fx.pointer_type)], + vec![AbiParam::new(to_ty)], + &args, + )[0]; + } else { + return fx.lib_call( + &name, + vec![AbiParam::new(types::I128)], + vec![AbiParam::new(to_ty)], + &[from], + )[0]; + } } // int-like -> float diff --git a/src/lib.rs b/src/lib.rs index c7fe382bac4e3..5b69bc7cc9b3d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -188,7 +188,7 @@ impl CodegenBackend for CraneliftCodegenBackend { } fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec { - vec![] + vec![Symbol::intern("llvm14-builtins-abi")] } fn print_version(&self) { From 7bd3b771b0882768f4f76116a7e8d08d0e418dbb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 16 Feb 2023 19:29:38 +0000 Subject: [PATCH 022/124] Add fixme --- src/cast.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cast.rs b/src/cast.rs index 0ab29f335a0fb..a474acedcb03b 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -65,6 +65,7 @@ pub(crate) fn clif_int_or_float_cast( ); if fx.tcx.sess.target.is_like_windows { + // FIXME move this logic into lib_call let arg_place = CPlace::new_stack_slot( fx, fx.layout_of(if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }), From ede7cde065d94fa53127c70c7db7f86c58eb749f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 10:24:06 +0000 Subject: [PATCH 023/124] Move windows i128 argument by-ref handling to lib_call --- src/abi/mod.rs | 22 +++++++++++++++++++ src/cast.rs | 29 ++++++------------------- src/codegen_i128.rs | 52 +++++++++++---------------------------------- 3 files changed, 40 insertions(+), 63 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 64bc9ab6aab41..4f8ede9cfbc44 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -117,6 +117,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { returns: Vec, args: &[Value], ) -> &[Value] { + if self.tcx.sess.target.is_like_windows + && params.iter().any(|param| param.value_type == types::I128) + { + let (params, args): (Vec<_>, Vec<_>) = + params + .into_iter() + .zip(args) + .map(|(param, &arg)| { + if param.value_type == types::I128 { + let arg_ptr = Pointer::stack_slot(self.bcx.create_sized_stack_slot( + StackSlotData { kind: StackSlotKind::ExplicitSlot, size: 16 }, + )); + arg_ptr.store(self, arg, MemFlags::trusted()); + (AbiParam::new(self.pointer_type), arg_ptr.get_addr(self)) + } else { + (param, arg) + } + }) + .unzip(); + return self.lib_call(name, params, returns, &args); + } + let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv }; let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap(); let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func); diff --git a/src/cast.rs b/src/cast.rs index a474acedcb03b..8c23152cda786 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -64,29 +64,12 @@ pub(crate) fn clif_int_or_float_cast( }, ); - if fx.tcx.sess.target.is_like_windows { - // FIXME move this logic into lib_call - let arg_place = CPlace::new_stack_slot( - fx, - fx.layout_of(if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }), - ); - let arg_ptr = arg_place.to_ptr(); - arg_ptr.store(fx, from, MemFlags::trusted()); - let args = [arg_ptr.get_addr(fx)]; - return fx.lib_call( - &name, - vec![AbiParam::new(fx.pointer_type)], - vec![AbiParam::new(to_ty)], - &args, - )[0]; - } else { - return fx.lib_call( - &name, - vec![AbiParam::new(types::I128)], - vec![AbiParam::new(to_ty)], - &[from], - )[0]; - } + return fx.lib_call( + &name, + vec![AbiParam::new(types::I128)], + vec![AbiParam::new(to_ty)], + &[from], + )[0]; } // int-like -> float diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index af3356e8213d9..c2a2ce8ad6a1a 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -32,21 +32,14 @@ pub(crate) fn maybe_codegen<'tcx>( let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; if fx.tcx.sess.target.is_like_windows { let ret_place = CPlace::new_stack_slot(fx, lhs.layout()); - let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); - let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); - assert!(lhs_extra.is_none()); - assert!(rhs_extra.is_none()); - let args = [ - ret_place.to_ptr().get_addr(fx), - lhs_ptr.get_addr(fx), - rhs_ptr.get_addr(fx), - ]; + let args = + [ret_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; fx.lib_call( "__multi3", vec![ AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), - AbiParam::new(fx.pointer_type), - AbiParam::new(fx.pointer_type), + AbiParam::new(types::I128), + AbiParam::new(types::I128), ], vec![], &args, @@ -87,29 +80,12 @@ pub(crate) fn maybe_codegen<'tcx>( assert!(checked); let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); - let (param_types, args) = if fx.tcx.sess.target.is_like_windows { - let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); - let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); - assert!(lhs_extra.is_none()); - assert!(rhs_extra.is_none()); - ( - vec![ - AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), - AbiParam::new(fx.pointer_type), - AbiParam::new(fx.pointer_type), - ], - [out_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)], - ) - } else { - ( - vec![ - AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), - AbiParam::new(types::I128), - AbiParam::new(types::I128), - ], - [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)], - ) - }; + let param_types = vec![ + AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), + AbiParam::new(types::I128), + AbiParam::new(types::I128), + ]; + let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; let name = match (bin_op, is_signed) { (BinOp::Add, false) => "__rust_u128_addo", (BinOp::Add, true) => "__rust_i128_addo", @@ -132,14 +108,10 @@ pub(crate) fn maybe_codegen<'tcx>( _ => unreachable!(), }; if fx.tcx.sess.target.is_like_windows { - let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); - let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); - assert!(lhs_extra.is_none()); - assert!(rhs_extra.is_none()); - let args = [lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)]; + let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)]; let ret = fx.lib_call( name, - vec![AbiParam::new(fx.pointer_type), AbiParam::new(fx.pointer_type)], + vec![AbiParam::new(types::I128), AbiParam::new(types::I128)], vec![AbiParam::new(types::I64X2)], &args, )[0]; From c6a0d3716b3ffa5be96c161bb4d82ea007463021 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 10:41:31 +0000 Subject: [PATCH 024/124] Move windows i128 indirect return handling to lib_call --- src/abi/mod.rs | 25 +++++++++++++++++++++---- src/codegen_i128.rs | 39 ++++++++++++--------------------------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 4f8ede9cfbc44..f1c3ea61636b4 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -4,6 +4,8 @@ mod comments; mod pass_mode; mod returning; +use std::borrow::Cow; + use cranelift_module::ModuleError; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::layout::FnAbiOf; @@ -116,11 +118,11 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { params: Vec, returns: Vec, args: &[Value], - ) -> &[Value] { + ) -> Cow<'_, [Value]> { if self.tcx.sess.target.is_like_windows && params.iter().any(|param| param.value_type == types::I128) { - let (params, args): (Vec<_>, Vec<_>) = + let (mut params, mut args): (Vec<_>, Vec<_>) = params .into_iter() .zip(args) @@ -136,7 +138,22 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { } }) .unzip(); - return self.lib_call(name, params, returns, &args); + + let indirect_ret_val = returns.len() == 1 && returns[0].value_type == types::I128; + + if indirect_ret_val { + params.insert(0, AbiParam::new(types::I128)); + let ret_ptr = + Pointer::stack_slot(self.bcx.create_sized_stack_slot(StackSlotData { + kind: StackSlotKind::ExplicitSlot, + size: 16, + })); + args.insert(0, ret_ptr.get_addr(self)); + self.lib_call(name, params, vec![], &args); + return Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())]); + } else { + return self.lib_call(name, params, returns, &args); + } } let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv }; @@ -151,7 +168,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { } let results = self.bcx.inst_results(call_inst); assert!(results.len() <= 2, "{}", results.len()); - results + Cow::Borrowed(results) } } diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index c2a2ce8ad6a1a..6640f0f358780 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -29,32 +29,17 @@ pub(crate) fn maybe_codegen<'tcx>( BinOp::Add | BinOp::Sub if !checked => None, BinOp::Mul if !checked || is_signed => { if !checked { - let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; - if fx.tcx.sess.target.is_like_windows { - let ret_place = CPlace::new_stack_slot(fx, lhs.layout()); - let args = - [ret_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; - fx.lib_call( - "__multi3", - vec![ - AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), - AbiParam::new(types::I128), - AbiParam::new(types::I128), - ], - vec![], - &args, - ); - Some(ret_place.to_cvalue(fx)) - } else { - let args: Vec<_> = vec![lhs.load_scalar(fx), rhs.load_scalar(fx)]; - let ret_val = fx.lib_call( - "__multi3", - vec![AbiParam::new(types::I128), AbiParam::new(types::I128)], - vec![AbiParam::new(types::I128)], - &args, - )[0]; - Some(CValue::by_val(ret_val, fx.layout_of(val_ty))) - } + let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)]; + let ret_val = fx.lib_call( + "__multi3", + vec![AbiParam::new(types::I128), AbiParam::new(types::I128)], + vec![AbiParam::new(types::I128)], + &args, + )[0]; + Some(CValue::by_val( + ret_val, + fx.layout_of(if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }), + )) } else { let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32)); @@ -120,7 +105,7 @@ pub(crate) fn maybe_codegen<'tcx>( ret_place.to_ptr().store(fx, ret, MemFlags::trusted()); Some(ret_place.to_cvalue(fx)) } else { - let args: Vec<_> = vec![lhs.load_scalar(fx), rhs.load_scalar(fx)]; + let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)]; let ret_val = fx.lib_call( name, vec![AbiParam::new(types::I128), AbiParam::new(types::I128)], From 29ad465127eb9f048e02a0b320e59cb0c7717134 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:31:41 +0000 Subject: [PATCH 025/124] Fix float to int compiler builtin call abi --- src/cast.rs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/cast.rs b/src/cast.rs index 8c23152cda786..032d1151041db 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -96,12 +96,29 @@ pub(crate) fn clif_int_or_float_cast( }, ); - fx.lib_call( - &name, - vec![AbiParam::new(from_ty)], - vec![AbiParam::new(types::I128)], - &[from], - )[0] + if fx.tcx.sess.target.is_like_windows { + let ret = fx.lib_call( + &name, + vec![AbiParam::new(from_ty)], + vec![AbiParam::new(types::I64X2)], + &[from], + )[0]; + // FIXME use bitcast instead of store to get from i64x2 to i128 + let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData { + kind: StackSlotKind::ExplicitSlot, + size: 16, + }); + let ret_ptr = Pointer::stack_slot(stack_slot); + ret_ptr.store(fx, ret, MemFlags::trusted()); + ret_ptr.load(fx, types::I128, MemFlags::trusted()) + } else { + fx.lib_call( + &name, + vec![AbiParam::new(from_ty)], + vec![AbiParam::new(types::I128)], + &[from], + )[0] + } } else if to_ty == types::I8 || to_ty == types::I16 { // FIXME implement fcvt_to_*int_sat.i8/i16 let val = if to_signed { From 54648091dd65ecc2b414399916d6fea96ab4d0a9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:46:32 +0000 Subject: [PATCH 026/124] Update to compiler-builtins 0.1.87 --- build_sysroot/Cargo.lock | 4 +-- build_sysroot/Cargo.toml | 3 +-- ...owngrade-compiler-builtins-to-0.1.86.patch | 26 ------------------- src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 31 deletions(-) delete mode 100644 patches/0029-sysroot-Downgrade-compiler-builtins-to-0.1.86.patch diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index b7e0b68a2a27a..3f9b374be23fa 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.86" +version = "0.1.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dae98c88e576098d7ab13ebcb40cc43e5114b2beafe61a87cda9200649ff205" +checksum = "f867ce54c09855ccd135ad4a50c777182a0c7af5ff20a8f537617bd648b10d50" dependencies = [ "rustc-std-workspace-core", ] diff --git a/build_sysroot/Cargo.toml b/build_sysroot/Cargo.toml index cde60ce2e05a9..8219e6b6ccf3b 100644 --- a/build_sysroot/Cargo.toml +++ b/build_sysroot/Cargo.toml @@ -8,8 +8,7 @@ alloc = { path = "./sysroot_src/library/alloc" } std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] } test = { path = "./sysroot_src/library/test" } -# FIXME allow 0.1.87 and later once #1353 is fixed -compiler_builtins = { version = "=0.1.86", default-features = false, features = ["no-asm"] } +compiler_builtins = { version = "0.1.87", default-features = false, features = ["no-asm"] } [patch.crates-io] rustc-std-workspace-core = { path = "./sysroot_src/library/rustc-std-workspace-core" } diff --git a/patches/0029-sysroot-Downgrade-compiler-builtins-to-0.1.86.patch b/patches/0029-sysroot-Downgrade-compiler-builtins-to-0.1.86.patch deleted file mode 100644 index c5fa6aaec2bd0..0000000000000 --- a/patches/0029-sysroot-Downgrade-compiler-builtins-to-0.1.86.patch +++ /dev/null @@ -1,26 +0,0 @@ -From ff23f6113098987318b674088b924e22750be18c Mon Sep 17 00:00:00 2001 -From: bjorn3 <17426603+bjorn3@users.noreply.github.com> -Date: Fri, 17 Feb 2023 18:37:48 +0100 -Subject: [PATCH] Downgrade compiler-builtins to 0.1.86 - -0.1.87 doesn't work on Windows when using cg_clif ---- - library/std/Cargo.toml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml -index 349cd91..300f812 100644 ---- a/library/std/Cargo.toml -+++ b/library/std/Cargo.toml -@@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true } - panic_abort = { path = "../panic_abort" } - core = { path = "../core" } - libc = { version = "0.2.138", default-features = false, features = ['rustc-dep-of-std'] } --compiler_builtins = { version = "0.1.87" } -+compiler_builtins = { version = "0.1.86" } - profiler_builtins = { path = "../profiler_builtins", optional = true } - unwind = { path = "../unwind" } - hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] } --- -2.26.2.7.g19db9cfb68 - diff --git a/src/lib.rs b/src/lib.rs index 5b69bc7cc9b3d..c7fe382bac4e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -188,7 +188,7 @@ impl CodegenBackend for CraneliftCodegenBackend { } fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec { - vec![Symbol::intern("llvm14-builtins-abi")] + vec![] } fn print_version(&self) { From dd5ffc2e18d145f292068095fef543c83bc9a16a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 19:29:06 +0000 Subject: [PATCH 027/124] Split out lib_call_unadjusted function --- src/abi/mod.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index f1c3ea61636b4..55c5d6d7a8b48 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -149,13 +149,23 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { size: 16, })); args.insert(0, ret_ptr.get_addr(self)); - self.lib_call(name, params, vec![], &args); + self.lib_call_unadjusted(name, params, vec![], &args); return Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())]); } else { - return self.lib_call(name, params, returns, &args); + return self.lib_call_unadjusted(name, params, returns, &args); } } + self.lib_call_unadjusted(name, params, returns, args) + } + + pub(crate) fn lib_call_unadjusted( + &mut self, + name: &str, + params: Vec, + returns: Vec, + args: &[Value], + ) -> Cow<'_, [Value]> { let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv }; let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap(); let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func); From a7c0cfc11398906daefb4aae715f9a065f58e378 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Feb 2023 19:39:07 +0000 Subject: [PATCH 028/124] Fix return address type --- src/abi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 55c5d6d7a8b48..2ed2dc84bc80e 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -142,7 +142,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let indirect_ret_val = returns.len() == 1 && returns[0].value_type == types::I128; if indirect_ret_val { - params.insert(0, AbiParam::new(types::I128)); + params.insert(0, AbiParam::new(self.pointer_type)); let ret_ptr = Pointer::stack_slot(self.bcx.create_sized_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, From 90a7ee6c70a3d553ed5fab12a64678b5ca263e94 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 18 Feb 2023 16:40:06 +0100 Subject: [PATCH 029/124] Check output of checked_div in std_example --- example/std_example.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index 8481d9c39a3cf..67c1e376d7a71 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -58,8 +58,8 @@ fn main() { assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7); assert_eq!(core::intrinsics::saturating_sub(0, -170141183460469231731687303715884105728i128), 170141183460469231731687303715884105727i128); - let _d = 0i128.checked_div(2i128); - let _d = 0u128.checked_div(2u128); + assert!(0i128.checked_div(2i128).is_some()); + assert!(0u128.checked_div(2u128).is_some()); assert_eq!(1u128 + 2, 3); assert_eq!(0b100010000000000000000000000000000u128 >> 10, 0b10001000000000000000000u128); From 4991d08bc69f3151ccb55c74e59792910f0776ca Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 18 Feb 2023 16:40:21 +0100 Subject: [PATCH 030/124] Remove incorrect check in lib_call --- src/abi/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 2ed2dc84bc80e..a713fd6814fbf 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -119,9 +119,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { returns: Vec, args: &[Value], ) -> Cow<'_, [Value]> { - if self.tcx.sess.target.is_like_windows - && params.iter().any(|param| param.value_type == types::I128) - { + if self.tcx.sess.target.is_like_windows { let (mut params, mut args): (Vec<_>, Vec<_>) = params .into_iter() From bb933d26dc722315d07d0f048e4185f40d94db8c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 18 Feb 2023 18:32:37 +0100 Subject: [PATCH 031/124] Fix abi for checked multiplication --- example/std_example.rs | 1 + src/codegen_i128.rs | 2 +- src/compiler_builtins.rs | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/example/std_example.rs b/example/std_example.rs index 67c1e376d7a71..e34b35d5c4a8c 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -58,6 +58,7 @@ fn main() { assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7); assert_eq!(core::intrinsics::saturating_sub(0, -170141183460469231731687303715884105728i128), 170141183460469231731687303715884105727i128); + std::hint::black_box(std::hint::black_box(7571400400375753350092698930310845914i128) * 10); assert!(0i128.checked_div(2i128).is_some()); assert!(0u128.checked_div(2u128).is_some()); assert_eq!(1u128 + 2, 3); diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index 6640f0f358780..cb048c0ad45bc 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -46,7 +46,7 @@ pub(crate) fn maybe_codegen<'tcx>( let lhs = lhs.load_scalar(fx); let rhs = rhs.load_scalar(fx); let oflow_ptr = oflow.to_ptr().get_addr(fx); - let res = fx.lib_call( + let res = fx.lib_call_unadjusted( "__muloti4", vec![ AbiParam::new(types::I128), diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs index 8a53baa763a7d..f3b963200a0fb 100644 --- a/src/compiler_builtins.rs +++ b/src/compiler_builtins.rs @@ -39,6 +39,7 @@ builtin_functions! { // integers fn __multi3(a: i128, b: i128) -> i128; + fn __muloti4(n: i128, d: i128, oflow: &mut i32) -> i128; fn __udivti3(n: u128, d: u128) -> u128; fn __divti3(n: i128, d: i128) -> i128; fn __umodti3(n: u128, d: u128) -> u128; From 39068eb1cc172335f9f3933cba0008bc263ce3ab Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 15 Feb 2023 18:46:56 +0000 Subject: [PATCH 032/124] Adapt cg_clif. --- src/base.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/base.rs b/src/base.rs index 95778de3abafc..7f857528c7c5c 100644 --- a/src/base.rs +++ b/src/base.rs @@ -347,7 +347,12 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => { if !fx.tcx.sess.overflow_checks() { - if let mir::AssertKind::OverflowNeg(_) = *msg { + let overflow_not_to_check = match msg { + AssertKind::OverflowNeg(..) => true, + AssertKind::Overflow(op, ..) => op.is_checkable(), + _ => false, + }; + if overflow_not_to_check { let target = fx.get_block(*target); fx.bcx.ins().jump(target, &[]); continue; @@ -567,15 +572,7 @@ fn codegen_stmt<'tcx>( let lhs = codegen_operand(fx, &lhs_rhs.0); let rhs = codegen_operand(fx, &lhs_rhs.1); - let res = if !fx.tcx.sess.overflow_checks() { - let val = - crate::num::codegen_int_binop(fx, bin_op, lhs, rhs).load_scalar(fx); - let is_overflow = fx.bcx.ins().iconst(types::I8, 0); - CValue::by_val_pair(val, is_overflow, lval.layout()) - } else { - crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs) - }; - + let res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs); lval.write_cvalue(fx, res); } Rvalue::UnaryOp(un_op, ref operand) => { From 8996171e8891d8b1f715a6e39b28753860113e56 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 18 Feb 2023 22:06:29 +0000 Subject: [PATCH 033/124] Stop implementing _with_overflow intrinsics in codegen backends. --- src/intrinsics/mod.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 0d2367c2f83d3..6feb3a7732e12 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -493,20 +493,6 @@ fn codegen_regular_intrinsic_call<'tcx>( let res = crate::num::codegen_int_binop(fx, bin_op, x, y); ret.write_cvalue(fx, res); } - sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => { - intrinsic_args!(fx, args => (x, y); intrinsic); - - assert_eq!(x.layout().ty, y.layout().ty); - let bin_op = match intrinsic { - sym::add_with_overflow => BinOp::Add, - sym::sub_with_overflow => BinOp::Sub, - sym::mul_with_overflow => BinOp::Mul, - _ => unreachable!(), - }; - - let res = crate::num::codegen_checked_int_binop(fx, bin_op, x, y); - ret.write_cvalue(fx, res); - } sym::saturating_add | sym::saturating_sub => { intrinsic_args!(fx, args => (lhs, rhs); intrinsic); From 746008e791a31578eae7eb70fe1271590f2045fa Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 10:41:09 +0100 Subject: [PATCH 034/124] Rustup to rustc 1.69.0-nightly (4507fdaaa 2023-02-18) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 96afb402476ec..98213e29ed1ce 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-17" +channel = "nightly-2023-02-19" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 98ddd69aaeec6bebaf30637a8beb1da47281af87 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 15:28:01 +0000 Subject: [PATCH 035/124] Add wrappers to dist/bin/ too in addition to dist/ Rust's build system since recently expects rustc to be in a bin/ directory if it is specified using the rustc option in config.toml. --- build_system/build_sysroot.rs | 4 +++- scripts/cargo-clif.rs | 6 +++++- scripts/rustc-clif.rs | 7 +++++-- scripts/rustdoc-clif.rs | 6 +++++- scripts/setup_rust_fork.sh | 2 +- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 62a025b4f8f75..4fb77c35c707c 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -46,13 +46,15 @@ pub(crate) fn build_sysroot( let wrapper_name = wrapper_base_name.replace("____", wrapper); let mut build_cargo_wrapper_cmd = Command::new(&bootstrap_host_compiler.rustc); + let wrapper_path = DIST_DIR.to_path(dirs).join(&wrapper_name); build_cargo_wrapper_cmd .env("TOOLCHAIN_NAME", toolchain_name.clone()) .arg(RelPath::SCRIPTS.to_path(dirs).join(&format!("{wrapper}.rs"))) .arg("-o") - .arg(DIST_DIR.to_path(dirs).join(wrapper_name)) + .arg(&wrapper_path) .arg("-Cstrip=debuginfo"); spawn_and_wait(build_cargo_wrapper_cmd); + try_hard_link(wrapper_path, BIN_DIR.to_path(dirs).join(wrapper_name)); } let host = build_sysroot_for_triple( diff --git a/scripts/cargo-clif.rs b/scripts/cargo-clif.rs index c993430b830b6..67791a203272d 100644 --- a/scripts/cargo-clif.rs +++ b/scripts/cargo-clif.rs @@ -5,7 +5,11 @@ use std::path::PathBuf; use std::process::Command; fn main() { - let sysroot = PathBuf::from(env::current_exe().unwrap().parent().unwrap()); + let current_exe = env::current_exe().unwrap(); + let mut sysroot = current_exe.parent().unwrap(); + if sysroot.file_name().unwrap().to_str().unwrap() == "bin" { + sysroot = sysroot.parent().unwrap(); + } let mut rustflags = String::new(); rustflags.push_str(" -Cpanic=abort -Zpanic-abort-tests -Zcodegen-backend="); diff --git a/scripts/rustc-clif.rs b/scripts/rustc-clif.rs index c187f54a60e77..b9bba7f2e084c 100644 --- a/scripts/rustc-clif.rs +++ b/scripts/rustc-clif.rs @@ -2,11 +2,14 @@ use std::env; use std::ffi::OsString; #[cfg(unix)] use std::os::unix::process::CommandExt; -use std::path::PathBuf; use std::process::Command; fn main() { - let sysroot = PathBuf::from(env::current_exe().unwrap().parent().unwrap()); + let current_exe = env::current_exe().unwrap(); + let mut sysroot = current_exe.parent().unwrap(); + if sysroot.file_name().unwrap().to_str().unwrap() == "bin" { + sysroot = sysroot.parent().unwrap(); + } let cg_clif_dylib_path = sysroot.join(if cfg!(windows) { "bin" } else { "lib" }).join( env::consts::DLL_PREFIX.to_string() + "rustc_codegen_cranelift" + env::consts::DLL_SUFFIX, diff --git a/scripts/rustdoc-clif.rs b/scripts/rustdoc-clif.rs index a6528ac41aee0..82c761634c779 100644 --- a/scripts/rustdoc-clif.rs +++ b/scripts/rustdoc-clif.rs @@ -6,7 +6,11 @@ use std::path::PathBuf; use std::process::Command; fn main() { - let sysroot = PathBuf::from(env::current_exe().unwrap().parent().unwrap()); + let current_exe = env::current_exe().unwrap(); + let mut sysroot = current_exe.parent().unwrap(); + if sysroot.file_name().unwrap().to_str().unwrap() == "bin" { + sysroot = sysroot.parent().unwrap(); + } let cg_clif_dylib_path = sysroot.join(if cfg!(windows) { "bin" } else { "lib" }).join( env::consts::DLL_PREFIX.to_string() + "rustc_codegen_cranelift" + env::consts::DLL_SUFFIX, diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh index a08e80dd19abc..35aa398449141 100644 --- a/scripts/setup_rust_fork.sh +++ b/scripts/setup_rust_fork.sh @@ -36,7 +36,7 @@ changelog-seen = 2 ninja = false [build] -rustc = "$(pwd)/../dist/rustc-clif" +rustc = "$(pwd)/../dist/bin/rustc-clif" cargo = "$(rustup which cargo)" full-bootstrap = true local-rebuild = true From c794dc7255402b4a2a97c577981e301810514d9a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 17:08:52 +0000 Subject: [PATCH 036/124] Enable inline stack probes on riscv64 Fixes #1358 --- src/lib.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c7fe382bac4e3..d8fe0f2538e6d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -280,14 +280,17 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box Date: Sun, 19 Feb 2023 17:11:28 +0000 Subject: [PATCH 037/124] Fix warnings --- scripts/cargo-clif.rs | 1 - scripts/rustdoc-clif.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/scripts/cargo-clif.rs b/scripts/cargo-clif.rs index 67791a203272d..939a1f1ca5900 100644 --- a/scripts/cargo-clif.rs +++ b/scripts/cargo-clif.rs @@ -1,7 +1,6 @@ use std::env; #[cfg(unix)] use std::os::unix::process::CommandExt; -use std::path::PathBuf; use std::process::Command; fn main() { diff --git a/scripts/rustdoc-clif.rs b/scripts/rustdoc-clif.rs index 82c761634c779..167631eaf7ee4 100644 --- a/scripts/rustdoc-clif.rs +++ b/scripts/rustdoc-clif.rs @@ -2,7 +2,6 @@ use std::env; use std::ffi::OsString; #[cfg(unix)] use std::os::unix::process::CommandExt; -use std::path::PathBuf; use std::process::Command; fn main() { From 9e6dfba38392febcd2be1322a4f90455c1187067 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 17:22:03 +0000 Subject: [PATCH 038/124] Allow codegen to unsize dyn* to dyn cg_clif counterpart to rust-lang/rust#106532 --- scripts/test_rustc_tests.sh | 1 - src/unsize.rs | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index e14a129dbc2d0..c44b34d96bdf4 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -113,7 +113,6 @@ rm tests/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered rm tests/ui/simd/intrinsic/generic-as.rs # crash when accessing vector type filed (#1318) rm tests/ui/simd/simd-bitmask.rs # crash -rm tests/ui/dyn-star/dyn-star-to-dyn.rs rm tests/ui/dyn-star/dispatch-on-pin-mut.rs # bugs in the test suite diff --git a/src/unsize.rs b/src/unsize.rs index e400d476db50e..ecf187a0b0fe6 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -28,9 +28,7 @@ pub(crate) fn unsized_info<'tcx>( ( &ty::Dynamic(ref data_a, _, src_dyn_kind), &ty::Dynamic(ref data_b, _, target_dyn_kind), - ) => { - assert_eq!(src_dyn_kind, target_dyn_kind); - + ) if src_dyn_kind == target_dyn_kind => { let old_info = old_info.expect("unsized_info: missing old info for trait upcasting coercion"); if data_a.principal_def_id() == data_b.principal_def_id() { From ef6df7e814329e05e369c6e9ed2833571be2e75a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 17:41:08 +0000 Subject: [PATCH 039/124] Handle wrappers around dyn* in receiver types Fixes #1324 --- scripts/test_rustc_tests.sh | 2 -- src/vtable.rs | 21 ++++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index c44b34d96bdf4..8d922f220659c 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -113,8 +113,6 @@ rm tests/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered rm tests/ui/simd/intrinsic/generic-as.rs # crash when accessing vector type filed (#1318) rm tests/ui/simd/simd-bitmask.rs # crash -rm tests/ui/dyn-star/dispatch-on-pin-mut.rs - # bugs in the test suite # ====================== rm tests/ui/backtrace.rs # TODO warning diff --git a/src/vtable.rs b/src/vtable.rs index f04fb82de8c81..b7bfd8fd39526 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -43,10 +43,29 @@ pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) - pub(crate) fn get_ptr_and_method_ref<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - arg: CValue<'tcx>, + mut arg: CValue<'tcx>, idx: usize, ) -> (Pointer, Value) { let (ptr, vtable) = 'block: { + if let Abi::Scalar(_) = arg.layout().abi { + 'descend_newtypes: while !arg.layout().ty.is_unsafe_ptr() + && !arg.layout().ty.is_region_ptr() + { + for i in 0..arg.layout().fields.count() { + let field = arg.value_field(fx, mir::Field::new(i)); + if !field.layout().is_zst() { + // we found the one non-zero-sized field that is allowed + // now find *its* non-zero-sized field, or stop if it's a + // pointer + arg = field; + continue 'descend_newtypes; + } + } + + bug!("receiver has no non-zero-sized fields {:?}", arg); + } + } + if let ty::Ref(_, ty, _) = arg.layout().ty.kind() { if ty.is_dyn_star() { let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty); From 916a6c17dfc53ac7535112fef3d256c56b282b12 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 17:46:51 +0000 Subject: [PATCH 040/124] Update portable-simd --- build_system/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index e9486888f86a4..41614834eb94a 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -107,7 +107,7 @@ pub(crate) static REGEX: CargoProject = CargoProject::new(®EX_REPO.source_dir pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github( "rust-lang", "portable-simd", - "582239ac3b32007613df04d7ffa78dc30f4c5645", + "9bd30e77b3a3c699af102ebb3df0f6110f8aa02e", "portable-simd", ); From 1af867cdf71965accfc30447bc80ff89deba0eff Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 17:55:35 +0000 Subject: [PATCH 041/124] Add test for #1318 --- example/mini_core_hello_world.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index c00f8a2e0cdad..39076f4902e16 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -1,4 +1,4 @@ -#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, box_syntax)] +#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, box_syntax, repr_simd)] #![no_core] #![allow(dead_code, non_camel_case_types)] @@ -339,7 +339,15 @@ fn main() { assert_eq!(unsafe { intrinsics::size_of_val(x) }, 0); assert_eq!(unsafe { intrinsics::min_align_of_val(x) }, 1); -} + } + + #[repr(simd)] + struct V([f64; 2]); + + unsafe { + let f = V([0.0, 1.0]); + let _a = f.0[0]; + } } #[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "darwin")))] From 37c269e16ab3365b8a23911cb7292e61fe1858b6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 17:56:34 +0000 Subject: [PATCH 042/124] Fix typo --- scripts/test_rustc_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 8d922f220659c..a82dd4474048a 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -110,7 +110,7 @@ rm tests/incremental/spike-neg2.rs # same rm tests/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors -rm tests/ui/simd/intrinsic/generic-as.rs # crash when accessing vector type filed (#1318) +rm tests/ui/simd/intrinsic/generic-as.rs # crash when accessing vector type field (#1318) rm tests/ui/simd/simd-bitmask.rs # crash # bugs in the test suite From f935dc82bca7fc6804a35770fe2b9efc5cdc132e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 18:02:18 +0000 Subject: [PATCH 043/124] Move abi-cafe runs to a separate workflow --- .github/workflows/abi-cafe.yml | 61 ++++++++++++++++++++++++++++++++++ .github/workflows/main.yml | 57 ------------------------------- 2 files changed, 61 insertions(+), 57 deletions(-) create mode 100644 .github/workflows/abi-cafe.yml diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml new file mode 100644 index 0000000000000..1d5bc621de0ba --- /dev/null +++ b/.github/workflows/abi-cafe.yml @@ -0,0 +1,61 @@ +name: CI + +on: + - push + +jobs: + abi_cafe: + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + + defaults: + run: + shell: bash + + strategy: + fail-fast: true + matrix: + include: + - os: ubuntu-latest + env: + TARGET_TRIPLE: x86_64-unknown-linux-gnu + - os: macos-latest + env: + TARGET_TRIPLE: x86_64-apple-darwin + - os: windows-latest + env: + TARGET_TRIPLE: x86_64-pc-windows-msvc + - os: windows-latest + env: + TARGET_TRIPLE: x86_64-pc-windows-gnu + + steps: + - uses: actions/checkout@v3 + + - name: Cache cargo target dir + uses: actions/cache@v3 + with: + path: build/cg_clif + key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + + - name: Set MinGW as the default toolchain + if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' + run: rustup set default-host x86_64-pc-windows-gnu + + - name: Use sparse cargo registry + run: | + cat >> ~/.cargo/config.toml <> ~/.cargo/config.toml < Date: Sun, 19 Feb 2023 18:03:09 +0000 Subject: [PATCH 044/124] Only allow a single abi-cafe run at a time per branch --- .github/workflows/abi-cafe.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index 1d5bc621de0ba..5f5510a579654 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -1,4 +1,4 @@ -name: CI +name: Abi-cafe on: - push @@ -7,6 +7,9 @@ jobs: abi_cafe: runs-on: ${{ matrix.os }} timeout-minutes: 60 + concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.env.TARGET_TRIPLE }} + cancel-in-progress: true defaults: run: From c6f48ebb1d5b2a37cb7780cee4b1a909f09d2712 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 18:22:15 +0000 Subject: [PATCH 045/124] Fix warning --- example/mini_core_hello_world.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 39076f4902e16..c323e72ba7805 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -344,10 +344,8 @@ fn main() { #[repr(simd)] struct V([f64; 2]); - unsafe { - let f = V([0.0, 1.0]); - let _a = f.0[0]; - } + let f = V([0.0, 1.0]); + let _a = f.0[0]; } #[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "darwin")))] From 5220e60ac63353735203afd1603f46609b5a4804 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Feb 2023 18:23:49 +0000 Subject: [PATCH 046/124] Rename build job to test --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c45f94b90c3e1..98b34c65dea59 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ jobs: rustfmt --check build_system/mod.rs - build: + test: runs-on: ${{ matrix.os }} timeout-minutes: 60 From 10c3c7207b78c07b195d17868963b0ae1e10d95d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 20 Feb 2023 12:33:39 +0100 Subject: [PATCH 047/124] Rustup to rustc 1.69.0-nightly (7aa413d59 2023-02-19) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 98213e29ed1ce..e1b403a4b8538 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-19" +channel = "nightly-2023-02-20" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From a563e1191841160e0399e24da14fe731b1fa463c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 1 Feb 2023 14:19:47 +0000 Subject: [PATCH 048/124] Update Cranelift to 0.93.0 Closes #1352 --- Cargo.lock | 49 ++++---- Cargo.toml | 14 +-- src/base.rs | 14 +-- src/cranelift_native.rs | 248 ---------------------------------------- src/intrinsics/simd.rs | 9 +- src/lib.rs | 4 +- 6 files changed, 40 insertions(+), 298 deletions(-) delete mode 100644 src/cranelift_native.rs diff --git a/Cargo.lock b/Cargo.lock index 50249ea1bdb49..4762d6dee158a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,18 +57,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3d54eab028f5805ae3b26fd60eca3f3a9cfb76b989d9bab173be3f61356cc3" +checksum = "91b18cf92869a6ae85cde3af4bc4beb6154efa8adef03b18db2ad413d5bce3a2" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2be1d5f2c3cca1efb691844bc1988b89c77291f13f778499a3f3c0cf49c0ed61" +checksum = "567d9f6e919bac076f39b902a072686eaf9e6d015baa34d10a61b85105b7af59" dependencies = [ "arrayvec", "bumpalo", @@ -87,30 +87,30 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9b1b1089750ce4005893af7ee00bb08a2cf1c9779999c0f7164cbc8ad2e0d2" +checksum = "1e72b2d5ec8917b2971fe83850187373d0a186db4748a7c23a5f48691b8d92bb" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5fbaec51de47297fd7304986fd53c8c0030abbe69728a60d72e1c63559318d" +checksum = "3461c0e0c2ebbeb92533aacb27e219289f60dc84134ef34fbf2d77c9eddf07ef" [[package]] name = "cranelift-entity" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab984c94593f876090fae92e984bdcc74d9b1acf740ab5f79036001c65cba13" +checksum = "af684f7f7b01427b1942c7102673322a51b9d6f261e9663dc5e5595786775531" [[package]] name = "cranelift-frontend" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0cb3102d21a2fe5f3210af608748ddd0cd09825ac12d42dc56ed5ed8725fe0" +checksum = "7d361ed0373cf5f086b49c499aa72227b646a64f899f32e34312f97c0fadff75" dependencies = [ "cranelift-codegen", "log", @@ -120,15 +120,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72101dd1f441d629735143c41e00b3428f9267738176983ef588ff43382af0a0" +checksum = "cef4f8f3984d772c199a48896d2fb766f96301bf71b371e03a2b99f4f3b7b931" [[package]] name = "cranelift-jit" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6557f8ce44d498777f2495aa58d9692a4a37d6f84aa445750d666cef770b6a5c" +checksum = "9c9909222db472fcc98d9e4e7192fa9d064dac63a3fa657df8c6daae86fb2604" dependencies = [ "anyhow", "cranelift-codegen", @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88807e1c0c47ec02fe433333ccbe56b480425418b1470e333205e11650697d72" +checksum = "68689b83e52e605ba48652882d3fccc2e2e136abf139eb64ae667888ba0d52f8" dependencies = [ "anyhow", "cranelift-codegen", @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22b0d9fcbe3fc5a1af9e7021b44ce42b930bcefac446ce22e02e8f9a0d67120" +checksum = "f98e4e99a353703475d5acb402b9c13482d41d8a4008b352559bd560afb90363" dependencies = [ "cranelift-codegen", "libc", @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.92.0" +version = "0.93.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "341375758d7c3fedc0b5315f552e6f0feac46baf87c450a15e9455ef47c2b261" +checksum = "b7a006ce1d8dd11df67567d8673e5920f3a56441812aed52a007ffce8f1b20e9" dependencies = [ "anyhow", "cranelift-codegen", @@ -333,6 +333,7 @@ dependencies = [ "cranelift-frontend", "cranelift-jit", "cranelift-module", + "cranelift-native", "cranelift-object", "gimli", "indexmap", @@ -381,9 +382,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasmtime-jit-icache-coherence" -version = "5.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08fcba5ebd96da2a9f0747ab6337fe9788adfb3f63fa2c180520d665562d257e" +checksum = "ec1fd0f0dd79e7cc0f55b102e320d7c77ab76cd272008a8fd98e25b5777e2636" dependencies = [ "cfg-if", "libc", diff --git a/Cargo.toml b/Cargo.toml index 34117c2886feb..0e64fba6bec8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,14 +15,12 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.92", features = ["unwind", "all-arch"] } -cranelift-frontend = { version = "0.92" } -cranelift-module = { version = "0.92" } -# NOTE vendored as src/cranelift_native.rs -# FIXME revert back to the external crate with Cranelift 0.93 -#cranelift-native = { version = "0.92" } -cranelift-jit = { version = "0.92", optional = true } -cranelift-object = { version = "0.92" } +cranelift-codegen = { version = "0.93", features = ["unwind", "all-arch"] } +cranelift-frontend = { version = "0.93" } +cranelift-module = { version = "0.93" } +cranelift-native = { version = "0.93" } +cranelift-jit = { version = "0.93", optional = true } +cranelift-object = { version = "0.93" } target-lexicon = "0.12.0" gimli = { version = "0.26.0", default-features = false, features = ["write"]} object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } diff --git a/src/base.rs b/src/base.rs index bcbb93a7765fa..898b94ba4c807 100644 --- a/src/base.rs +++ b/src/base.rs @@ -365,11 +365,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { fx.bcx.set_cold_block(failure); if *expected { - fx.bcx.ins().brz(cond, failure, &[]); + fx.bcx.ins().brif(cond, target, &[], failure, &[]); } else { - fx.bcx.ins().brnz(cond, failure, &[]); + fx.bcx.ins().brif(cond, failure, &[], target, &[]); }; - fx.bcx.ins().jump(target, &[]); fx.bcx.switch_to_block(failure); fx.bcx.ins().nop(); @@ -425,11 +424,9 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } } else { if test_zero { - fx.bcx.ins().brz(discr, then_block, &[]); - fx.bcx.ins().jump(else_block, &[]); + fx.bcx.ins().brif(discr, else_block, &[], then_block, &[]); } else { - fx.bcx.ins().brnz(discr, then_block, &[]); - fx.bcx.ins().jump(else_block, &[]); + fx.bcx.ins().brif(discr, then_block, &[], else_block, &[]); } } } else { @@ -751,8 +748,7 @@ fn codegen_stmt<'tcx>( fx.bcx.switch_to_block(loop_block); let done = fx.bcx.ins().icmp_imm(IntCC::Equal, index, times as i64); - fx.bcx.ins().brnz(done, done_block, &[]); - fx.bcx.ins().jump(loop_block2, &[]); + fx.bcx.ins().brif(done, done_block, &[], loop_block2, &[]); fx.bcx.switch_to_block(loop_block2); let to = lval.place_index(fx, index); diff --git a/src/cranelift_native.rs b/src/cranelift_native.rs deleted file mode 100644 index 6c4efca442448..0000000000000 --- a/src/cranelift_native.rs +++ /dev/null @@ -1,248 +0,0 @@ -// Vendored from https://github.com/bytecodealliance/wasmtime/blob/b58a197d33f044193c3d608010f5e6ec394ac07e/cranelift/native/src/lib.rs -// which is licensed as -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// unlike rustc_codegen_cranelift itself. Also applies a small change to remove #![cfg_attr] that -// rust's CI complains about and to fix formatting to match rustc. -// FIXME revert back to the external crate with Cranelift 0.93 -#![allow(warnings)] - -//! Performs autodetection of the host for the purposes of running -//! Cranelift to generate code to run on the same machine. - -#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates, unstable_features)] -#![warn(unused_import_braces)] - -use cranelift_codegen::isa; -use target_lexicon::Triple; - -/// Return an `isa` builder configured for the current host -/// machine, or `Err(())` if the host machine is not supported -/// in the current configuration. -pub fn builder() -> Result { - builder_with_options(true) -} - -/// Return an `isa` builder configured for the current host -/// machine, or `Err(())` if the host machine is not supported -/// in the current configuration. -/// -/// Selects the given backend variant specifically; this is -/// useful when more than oen backend exists for a given target -/// (e.g., on x86-64). -pub fn builder_with_options(infer_native_flags: bool) -> Result { - let mut isa_builder = isa::lookup(Triple::host()).map_err(|err| match err { - isa::LookupError::SupportDisabled => "support for architecture disabled at compile time", - isa::LookupError::Unsupported => "unsupported architecture", - })?; - - #[cfg(target_arch = "x86_64")] - { - use cranelift_codegen::settings::Configurable; - - if !std::is_x86_feature_detected!("sse2") { - return Err("x86 support requires SSE2"); - } - - if !infer_native_flags { - return Ok(isa_builder); - } - - // These are temporarily enabled by default (see #3810 for - // more) so that a default-constructed `Flags` can work with - // default Wasmtime features. Otherwise, the user must - // explicitly use native flags or turn these on when on x86-64 - // platforms to avoid a configuration panic. In order for the - // "enable if detected" logic below to work, we must turn them - // *off* (differing from the default) and then re-enable below - // if present. - isa_builder.set("has_sse3", "false").unwrap(); - isa_builder.set("has_ssse3", "false").unwrap(); - isa_builder.set("has_sse41", "false").unwrap(); - isa_builder.set("has_sse42", "false").unwrap(); - - if std::is_x86_feature_detected!("sse3") { - isa_builder.enable("has_sse3").unwrap(); - } - if std::is_x86_feature_detected!("ssse3") { - isa_builder.enable("has_ssse3").unwrap(); - } - if std::is_x86_feature_detected!("sse4.1") { - isa_builder.enable("has_sse41").unwrap(); - } - if std::is_x86_feature_detected!("sse4.2") { - isa_builder.enable("has_sse42").unwrap(); - } - if std::is_x86_feature_detected!("popcnt") { - isa_builder.enable("has_popcnt").unwrap(); - } - if std::is_x86_feature_detected!("avx") { - isa_builder.enable("has_avx").unwrap(); - } - if std::is_x86_feature_detected!("avx2") { - isa_builder.enable("has_avx2").unwrap(); - } - if std::is_x86_feature_detected!("fma") { - isa_builder.enable("has_fma").unwrap(); - } - if std::is_x86_feature_detected!("bmi1") { - isa_builder.enable("has_bmi1").unwrap(); - } - if std::is_x86_feature_detected!("bmi2") { - isa_builder.enable("has_bmi2").unwrap(); - } - if std::is_x86_feature_detected!("avx512bitalg") { - isa_builder.enable("has_avx512bitalg").unwrap(); - } - if std::is_x86_feature_detected!("avx512dq") { - isa_builder.enable("has_avx512dq").unwrap(); - } - if std::is_x86_feature_detected!("avx512f") { - isa_builder.enable("has_avx512f").unwrap(); - } - if std::is_x86_feature_detected!("avx512vl") { - isa_builder.enable("has_avx512vl").unwrap(); - } - if std::is_x86_feature_detected!("avx512vbmi") { - isa_builder.enable("has_avx512vbmi").unwrap(); - } - if std::is_x86_feature_detected!("lzcnt") { - isa_builder.enable("has_lzcnt").unwrap(); - } - } - - #[cfg(target_arch = "aarch64")] - { - use cranelift_codegen::settings::Configurable; - - if !infer_native_flags { - return Ok(isa_builder); - } - - if std::arch::is_aarch64_feature_detected!("lse") { - isa_builder.enable("has_lse").unwrap(); - } - - if std::arch::is_aarch64_feature_detected!("paca") { - isa_builder.enable("has_pauth").unwrap(); - } - - if cfg!(target_os = "macos") { - // Pointer authentication is always available on Apple Silicon. - isa_builder.enable("sign_return_address").unwrap(); - // macOS enforces the use of the B key for return addresses. - isa_builder.enable("sign_return_address_with_bkey").unwrap(); - } - } - - // There is no is_s390x_feature_detected macro yet, so for now - // we use getauxval from the libc crate directly. - #[cfg(all(target_arch = "s390x", target_os = "linux"))] - { - use cranelift_codegen::settings::Configurable; - - if !infer_native_flags { - return Ok(isa_builder); - } - - let v = unsafe { libc::getauxval(libc::AT_HWCAP) }; - const HWCAP_S390X_VXRS_EXT2: libc::c_ulong = 32768; - if (v & HWCAP_S390X_VXRS_EXT2) != 0 { - isa_builder.enable("has_vxrs_ext2").unwrap(); - // There is no separate HWCAP bit for mie2, so assume - // that any machine with vxrs_ext2 also has mie2. - isa_builder.enable("has_mie2").unwrap(); - } - } - - // `is_riscv_feature_detected` is nightly only for now, use - // getauxval from the libc crate directly as a temporary measure. - #[cfg(all(target_arch = "riscv64", target_os = "linux"))] - { - use cranelift_codegen::settings::Configurable; - - if !infer_native_flags { - return Ok(isa_builder); - } - - let v = unsafe { libc::getauxval(libc::AT_HWCAP) }; - - const HWCAP_RISCV_EXT_A: libc::c_ulong = 1 << (b'a' - b'a'); - const HWCAP_RISCV_EXT_C: libc::c_ulong = 1 << (b'c' - b'a'); - const HWCAP_RISCV_EXT_D: libc::c_ulong = 1 << (b'd' - b'a'); - const HWCAP_RISCV_EXT_F: libc::c_ulong = 1 << (b'f' - b'a'); - const HWCAP_RISCV_EXT_M: libc::c_ulong = 1 << (b'm' - b'a'); - const HWCAP_RISCV_EXT_V: libc::c_ulong = 1 << (b'v' - b'a'); - - if (v & HWCAP_RISCV_EXT_A) != 0 { - isa_builder.enable("has_a").unwrap(); - } - - if (v & HWCAP_RISCV_EXT_C) != 0 { - isa_builder.enable("has_c").unwrap(); - } - - if (v & HWCAP_RISCV_EXT_D) != 0 { - isa_builder.enable("has_d").unwrap(); - } - - if (v & HWCAP_RISCV_EXT_F) != 0 { - isa_builder.enable("has_f").unwrap(); - - // TODO: There doesn't seem to be a bit associated with this extension - // rust enables it with the `f` extension: - // https://github.com/rust-lang/stdarch/blob/790411f93c4b5eada3c23abb4c9a063fb0b24d99/crates/std_detect/src/detect/os/linux/riscv.rs#L43 - isa_builder.enable("has_zicsr").unwrap(); - } - - if (v & HWCAP_RISCV_EXT_M) != 0 { - isa_builder.enable("has_m").unwrap(); - } - - if (v & HWCAP_RISCV_EXT_V) != 0 { - isa_builder.enable("has_v").unwrap(); - } - - // TODO: ZiFencei does not have a bit associated with it - // TODO: Zbkb does not have a bit associated with it - } - - // squelch warnings about unused mut/variables on some platforms. - drop(&mut isa_builder); - drop(infer_native_flags); - - Ok(isa_builder) -} - -#[cfg(test)] -mod tests { - use super::builder; - use cranelift_codegen::isa::CallConv; - use cranelift_codegen::settings; - - #[test] - fn test() { - if let Ok(isa_builder) = builder() { - let flag_builder = settings::builder(); - let isa = isa_builder.finish(settings::Flags::new(flag_builder)).unwrap(); - - if cfg!(all(target_os = "macos", target_arch = "aarch64")) { - assert_eq!(isa.default_call_conv(), CallConv::AppleAarch64); - } else if cfg!(any(unix, target_os = "nebulet")) { - assert_eq!(isa.default_call_conv(), CallConv::SystemV); - } else if cfg!(windows) { - assert_eq!(isa.default_call_conv(), CallConv::WindowsFastcall); - } - - if cfg!(target_pointer_width = "64") { - assert_eq!(isa.pointer_bits(), 64); - } else if cfg!(target_pointer_width = "32") { - assert_eq!(isa.pointer_bits(), 32); - } else if cfg!(target_pointer_width = "16") { - assert_eq!(isa.pointer_bits(), 16); - } - } - } -} - -/// Version number of this crate. -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index a1d63acfb6166..034b4e8072cc5 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -279,9 +279,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.tcx.sess.span_warn(span, "Index argument for `simd_extract` is not a constant"); let trap_block = fx.bcx.create_block(); let true_ = fx.bcx.ins().iconst(types::I8, 1); - fx.bcx.ins().brnz(true_, trap_block, &[]); let ret_block = fx.get_block(target); - fx.bcx.ins().jump(ret_block, &[]); + fx.bcx.ins().brif(true_, trap_block, &[], ret_block, &[]); fx.bcx.switch_to_block(trap_block); crate::trap::trap_unimplemented( fx, @@ -825,8 +824,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let next = fx.bcx.create_block(); let res_lane = fx.bcx.append_block_param(next, lane_clif_ty); - fx.bcx.ins().brnz(mask_lane, if_enabled, &[]); - fx.bcx.ins().jump(if_disabled, &[]); + fx.bcx.ins().brif(mask_lane, if_enabled, &[], if_disabled, &[]); fx.bcx.seal_block(if_enabled); fx.bcx.seal_block(if_disabled); @@ -864,8 +862,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let if_enabled = fx.bcx.create_block(); let next = fx.bcx.create_block(); - fx.bcx.ins().brnz(mask_lane, if_enabled, &[]); - fx.bcx.ins().jump(next, &[]); + fx.bcx.ins().brif(mask_lane, if_enabled, &[], next, &[]); fx.bcx.seal_block(if_enabled); fx.bcx.switch_to_block(if_enabled); diff --git a/src/lib.rs b/src/lib.rs index d8fe0f2538e6d..dd2fc1b1bb475 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,8 +57,6 @@ mod compiler_builtins; mod concurrency_limiter; mod config; mod constant; -// FIXME revert back to the external crate with Cranelift 0.93 -mod cranelift_native; mod debuginfo; mod discriminant; mod driver; @@ -246,7 +244,7 @@ fn target_triple(sess: &Session) -> target_lexicon::Triple { } } -fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box { +fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc { use target_lexicon::BinaryFormat; let target_triple = crate::target_triple(sess); From 93fdcfa554af34c01970db8ace1e724214913f8f Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 17 Oct 2022 14:11:26 +0100 Subject: [PATCH 049/124] various: translation resources from cg backend Extend `CodegenBackend` trait with a function returning the translation resources from the codegen backend, which can be added to the complete list of resources provided to the emitter. Signed-off-by: David Wood --- src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index c7fe382bac4e3..5ba568bfd6e87 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -172,6 +172,11 @@ pub struct CraneliftCodegenBackend { } impl CodegenBackend for CraneliftCodegenBackend { + fn locale_resource(&self) -> &'static str { + // FIXME(rust-lang/rust#100717) - cranelift codegen backend is not yet translated + "" + } + fn init(&self, sess: &Session) { use rustc_session::config::Lto; match sess.lto() { From d9751e46c7f5462e6183c14b3b8dd3ad95f1995e Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Wed, 22 Feb 2023 02:18:40 +0000 Subject: [PATCH 050/124] Remove type-traversal trait aliases --- src/common.rs | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common.rs b/src/common.rs index a8be0d32cc8c7..722e2754e8381 100644 --- a/src/common.rs +++ b/src/common.rs @@ -374,7 +374,7 @@ impl<'tcx> HasTargetSpec for FunctionCx<'_, '_, 'tcx> { impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) fn monomorphize(&self, value: T) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable> + Copy, { self.instance.subst_mir_and_normalize_erasing_regions( self.tcx, diff --git a/src/lib.rs b/src/lib.rs index c7fe382bac4e3..58154191c56bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,7 +86,7 @@ mod prelude { pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, - TypeFoldable, UintTy, + TypeFoldable, TypeVisitableExt, UintTy, }; pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx}; From 4036a5722a240f4c03ab269f29166502b3c6e4c8 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Wed, 22 Feb 2023 20:51:29 +0000 Subject: [PATCH 051/124] Unify validity checks into a single query Previously, there were two queries to check whether a type allows the 0x01 or zeroed bitpattern. I am planning on adding a further initness to check, truly uninit for MaybeUninit, which would make this three queries. This seems overkill for such a small feature, so this PR unifies them into one. --- src/intrinsics/mod.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 6feb3a7732e12..f00e932107058 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -21,7 +21,8 @@ mod simd; pub(crate) use cpuid::codegen_cpuid_call; pub(crate) use llvm::codegen_llvm_intrinsic_call; -use rustc_middle::ty::layout::HasParamEnv; +use rustc_middle::ty; +use rustc_middle::ty::layout::{HasParamEnv, InitKind}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::SubstsRef; use rustc_span::symbol::{kw, sym, Symbol}; @@ -642,7 +643,7 @@ fn codegen_regular_intrinsic_call<'tcx>( if intrinsic == sym::assert_zero_valid && !fx .tcx - .permits_zero_init(fx.param_env().and(ty)) + .check_validity_of_init((InitKind::Zero, fx.param_env().and(ty))) .expect("expected to have layout during codegen") { with_no_trimmed_paths!({ @@ -661,7 +662,10 @@ fn codegen_regular_intrinsic_call<'tcx>( if intrinsic == sym::assert_mem_uninitialized_valid && !fx .tcx - .permits_uninit_init(fx.param_env().and(ty)) + .check_validity_of_init(( + InitKind::UninitMitigated0x01Fill, + fx.param_env().and(ty), + )) .expect("expected to have layout during codegen") { with_no_trimmed_paths!({ From eb84167837f241e12f21a806b162cfdea277bdb2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 17 Feb 2023 14:33:08 +1100 Subject: [PATCH 052/124] Rename many interner functions. (This is a large commit. The changes to `compiler/rustc_middle/src/ty/context.rs` are the most important ones.) The current naming scheme is a mess, with a mix of `_intern_`, `intern_` and `mk_` prefixes, with little consistency. In particular, in many cases it's easy to use an iterator interner when a (preferable) slice interner is available. The guiding principles of the new naming system: - No `_intern_` prefixes. - The `intern_` prefix is for internal operations. - The `mk_` prefix is for external operations. - For cases where there is a slice interner and an iterator interner, the former is `mk_foo` and the latter is `mk_foo_from_iter`. Also, `slice_interners!` and `direct_interners!` can now be `pub` or non-`pub`, which helps enforce the internal/external operations division. It's not perfect, but I think it's a clear improvement. The following lists show everything that was renamed. slice_interners - const_list - mk_const_list -> mk_const_list_from_iter - intern_const_list -> mk_const_list - substs - mk_substs -> mk_substs_from_iter - intern_substs -> mk_substs - check_substs -> check_and_mk_substs (this is a weird one) - canonical_var_infos - intern_canonical_var_infos -> mk_canonical_var_infos - poly_existential_predicates - mk_poly_existential_predicates -> mk_poly_existential_predicates_from_iter - intern_poly_existential_predicates -> mk_poly_existential_predicates - _intern_poly_existential_predicates -> intern_poly_existential_predicates - predicates - mk_predicates -> mk_predicates_from_iter - intern_predicates -> mk_predicates - _intern_predicates -> intern_predicates - projs - intern_projs -> mk_projs - place_elems - mk_place_elems -> mk_place_elems_from_iter - intern_place_elems -> mk_place_elems - bound_variable_kinds - mk_bound_variable_kinds -> mk_bound_variable_kinds_from_iter - intern_bound_variable_kinds -> mk_bound_variable_kinds direct_interners - region - intern_region (unchanged) - const - mk_const_internal -> intern_const - const_allocation - intern_const_alloc -> mk_const_alloc - layout - intern_layout -> mk_layout - adt_def - intern_adt_def -> mk_adt_def_from_data (unusual case, hard to avoid) - alloc_adt_def(!) -> mk_adt_def - external_constraints - intern_external_constraints -> mk_external_constraints Other - type_list - mk_type_list -> mk_type_list_from_iter - intern_type_list -> mk_type_list - tup - mk_tup -> mk_tup_from_iter - intern_tup -> mk_tup --- src/abi/mod.rs | 6 +++--- src/codegen_i128.rs | 4 ++-- src/intrinsics/llvm_x86.rs | 2 +- src/main_shim.rs | 4 ++-- src/num.rs | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 3c34585d4191e..74396a66f54e0 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -405,9 +405,9 @@ pub(crate) fn codegen_terminator_call<'tcx>( }; let extra_args = &args[fn_sig.inputs().skip_binder().len()..]; - let extra_args = fx - .tcx - .mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx)))); + let extra_args = fx.tcx.mk_type_list_from_iter( + extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))), + ); let fn_abi = if let Some(instance) = instance { RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args) } else { diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index b4a2537b5ea93..40bfe70771c19 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -56,7 +56,7 @@ pub(crate) fn maybe_codegen<'tcx>( Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) } } else { - let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); + let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32)); let lhs = lhs.load_scalar(fx); let rhs = rhs.load_scalar(fx); @@ -78,7 +78,7 @@ pub(crate) fn maybe_codegen<'tcx>( } BinOp::Add | BinOp::Sub | BinOp::Mul => { assert!(checked); - let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); + let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); let (param_types, args) = if fx.tcx.sess.target.is_like_windows { let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index cbac2e667652b..e5c4b244a1afd 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -191,7 +191,7 @@ fn llvm_add_sub<'tcx>( // carry0 | carry1 -> carry or borrow respectively let cb_out = fx.bcx.ins().bor(cb0, cb1); - let layout = fx.layout_of(fx.tcx.intern_tup(&[fx.tcx.types.u8, fx.tcx.types.u64])); + let layout = fx.layout_of(fx.tcx.mk_tup(&[fx.tcx.types.u8, fx.tcx.types.u64])); let val = CValue::by_val_pair(cb_out, c, layout); ret.write_cvalue(fx, val); } diff --git a/src/main_shim.rs b/src/main_shim.rs index 26327107df4c5..be908df83e8f5 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper( tcx, ParamEnv::reveal_all(), report.def_id, - tcx.intern_substs(&[GenericArg::from(main_ret_ty)]), + tcx.mk_substs(&[GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap() @@ -146,7 +146,7 @@ pub(crate) fn maybe_create_entry_wrapper( tcx, ParamEnv::reveal_all(), start_def_id, - tcx.intern_substs(&[main_ret_ty.into()]), + tcx.mk_substs(&[main_ret_ty.into()]), ) .unwrap() .unwrap() diff --git a/src/num.rs b/src/num.rs index 05905a7bcdf30..c058ece96d8e3 100644 --- a/src/num.rs +++ b/src/num.rs @@ -289,7 +289,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs), }; - let out_layout = fx.layout_of(fx.tcx.intern_tup(&[in_lhs.layout().ty, fx.tcx.types.bool])); + let out_layout = fx.layout_of(fx.tcx.mk_tup(&[in_lhs.layout().ty, fx.tcx.types.bool])); CValue::by_val_pair(res, has_overflow, out_layout) } From fdfa277158fca61cf5058e1dc2dcac226c4c5e62 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 25 Feb 2023 18:17:06 +0100 Subject: [PATCH 053/124] Rustup to rustc 1.69.0-nightly (c5c7d2b37 2023-02-24) --- build_sysroot/Cargo.lock | 4 ++-- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index 3f9b374be23fa..586d47c1b72c7 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.87" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f867ce54c09855ccd135ad4a50c777182a0c7af5ff20a8f537617bd648b10d50" +checksum = "a2fbf11d629e314a85bc4d7348ee388d98ad0e8eb53182f3e5a17bc63613acd2" dependencies = [ "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index e1b403a4b8538..cfa3390b6d9ec 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-20" +channel = "nightly-2023-02-25" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 26d0d255ce4da75354dc6c7571bb44aa8279b5aa Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 25 Feb 2023 17:48:45 +0000 Subject: [PATCH 054/124] Reduce verbosity of libcore testing --- build_system/tests.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index 41614834eb94a..53d43caf9426a 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -137,7 +137,9 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ LIBCORE_TESTS.clean(&runner.dirs); if runner.is_native { - spawn_and_wait(LIBCORE_TESTS.test(&runner.target_compiler, &runner.dirs)); + let mut test_cmd = LIBCORE_TESTS.test(&runner.target_compiler, &runner.dirs); + test_cmd.arg("--").arg("-q"); + spawn_and_wait(test_cmd); } else { eprintln!("Cross-Compiling: Not running tests"); let mut build_cmd = LIBCORE_TESTS.build(&runner.target_compiler, &runner.dirs); From be19c03e6966d636ef696e23cc8a60669a2bb19c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 25 Feb 2023 17:54:01 +0000 Subject: [PATCH 055/124] Silence almost all warnings when compiling coretests --- patches/0022-sysroot-Disable-not-compiling-tests.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/patches/0022-sysroot-Disable-not-compiling-tests.patch b/patches/0022-sysroot-Disable-not-compiling-tests.patch index 865aa833a5eef..4db56fa3bd2c7 100644 --- a/patches/0022-sysroot-Disable-not-compiling-tests.patch +++ b/patches/0022-sysroot-Disable-not-compiling-tests.patch @@ -31,5 +31,14 @@ index 0000000..46fd999 +[dependencies] +rand = { version = "0.8.5", default-features = false } +rand_xorshift = { version = "0.3.0", default-features = false } +diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs +index 42a26ae..5ac1042 100644 +--- a/library/core/tests/lib.rs ++++ b/library/core/tests/lib.rs +@@ -1,3 +1,4 @@ ++#![cfg(test)] + #![feature(alloc_layout_extra)] + #![feature(array_chunks)] + #![feature(array_methods)] -- 2.21.0 (Apple Git-122) From f79601fbb09c50e47ade725ed350e02bcaeb55bc Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 25 Feb 2023 18:01:42 +0000 Subject: [PATCH 056/124] Reduce verbosity of rand testing --- build_system/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index 53d43caf9426a..c80784accaca0 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -124,7 +124,7 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ if runner.is_native { eprintln!("[TEST] rust-random/rand"); let mut test_cmd = RAND.test(&runner.target_compiler, &runner.dirs); - test_cmd.arg("--workspace"); + test_cmd.arg("--workspace").arg("--").arg("-q"); spawn_and_wait(test_cmd); } else { eprintln!("[AOT] rust-random/rand"); From a45a81a6a290d654d8906a099721d631fd361ee9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Feb 2023 12:15:25 +0000 Subject: [PATCH 057/124] Patch coretests separately from the standard library source --- build_system/prepare.rs | 29 +++++++++++++++--- build_system/tests.rs | 7 +++-- ...retests-Disable-not-compiling-tests.patch} | 12 ++++---- ...0023-coretests-Ignore-failing-tests.patch} | 12 ++++---- ...7-coretests-128bit-atomic-operations.patch | 30 +++++++++++++++++++ ...027-stdlib-128bit-atomic-operations.patch} | 15 ---------- ...oretests-Disable-long-running-tests.patch} | 6 ++-- scripts/setup_rust_fork.sh | 2 +- 8 files changed, 75 insertions(+), 38 deletions(-) rename patches/{0022-sysroot-Disable-not-compiling-tests.patch => 0022-coretests-Disable-not-compiling-tests.patch} (80%) rename patches/{0023-sysroot-Ignore-failing-tests.patch => 0023-coretests-Ignore-failing-tests.patch} (85%) create mode 100644 patches/0027-coretests-128bit-atomic-operations.patch rename patches/{0027-sysroot-128bit-atomic-operations.patch => 0027-stdlib-128bit-atomic-operations.patch} (83%) rename patches/{0028-sysroot-Disable-long-running-tests.patch => 0028-coretests-Disable-long-running-tests.patch} (89%) diff --git a/build_system/prepare.rs b/build_system/prepare.rs index 50b1b7836dee1..6769e42d44b94 100644 --- a/build_system/prepare.rs +++ b/build_system/prepare.rs @@ -6,6 +6,7 @@ use std::process::Command; use super::build_sysroot::{BUILD_SYSROOT, ORIG_BUILD_SYSROOT, SYSROOT_RUSTC_VERSION, SYSROOT_SRC}; use super::path::{Dirs, RelPath}; use super::rustc_info::{get_default_sysroot, get_rustc_version}; +use super::tests::LIBCORE_TESTS_SRC; use super::utils::{copy_dir_recursively, git_command, retry_spawn_and_wait, spawn_and_wait}; pub(crate) fn prepare(dirs: &Dirs) { @@ -13,8 +14,10 @@ pub(crate) fn prepare(dirs: &Dirs) { spawn_and_wait(super::build_backend::CG_CLIF.fetch("cargo", "rustc", dirs)); - prepare_sysroot(dirs); + prepare_stdlib(dirs); spawn_and_wait(super::build_sysroot::STANDARD_LIBRARY.fetch("cargo", "rustc", dirs)); + + prepare_coretests(dirs); spawn_and_wait(super::tests::LIBCORE_TESTS.fetch("cargo", "rustc", dirs)); super::tests::RAND_REPO.fetch(dirs); @@ -25,11 +28,11 @@ pub(crate) fn prepare(dirs: &Dirs) { spawn_and_wait(super::tests::PORTABLE_SIMD.fetch("cargo", "rustc", dirs)); } -fn prepare_sysroot(dirs: &Dirs) { +fn prepare_stdlib(dirs: &Dirs) { let sysroot_src_orig = get_default_sysroot(Path::new("rustc")).join("lib/rustlib/src/rust"); assert!(sysroot_src_orig.exists()); - eprintln!("[COPY] sysroot src"); + eprintln!("[COPY] stdlib src"); // FIXME ensure builds error out or update the copy if any of the files copied here change BUILD_SYSROOT.ensure_fresh(dirs); @@ -47,7 +50,25 @@ fn prepare_sysroot(dirs: &Dirs) { eprintln!("[GIT] init"); init_git_repo(&SYSROOT_SRC.to_path(dirs)); - apply_patches(dirs, "sysroot", &SYSROOT_SRC.to_path(dirs)); + apply_patches(dirs, "stdlib", &SYSROOT_SRC.to_path(dirs)); +} + +fn prepare_coretests(dirs: &Dirs) { + let sysroot_src_orig = get_default_sysroot(Path::new("rustc")).join("lib/rustlib/src/rust"); + assert!(sysroot_src_orig.exists()); + + eprintln!("[COPY] coretests src"); + + fs::create_dir_all(LIBCORE_TESTS_SRC.to_path(dirs)).unwrap(); + copy_dir_recursively( + &sysroot_src_orig.join("library/core/tests"), + &LIBCORE_TESTS_SRC.to_path(dirs), + ); + + eprintln!("[GIT] init"); + init_git_repo(&LIBCORE_TESTS_SRC.to_path(dirs)); + + apply_patches(dirs, "coretests", &LIBCORE_TESTS_SRC.to_path(dirs)); } pub(crate) struct GitRepo { diff --git a/build_system/tests.rs b/build_system/tests.rs index c80784accaca0..b55187aa3b4c9 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -1,4 +1,4 @@ -use super::build_sysroot::{self, SYSROOT_SRC}; +use super::build_sysroot; use super::config; use super::path::{Dirs, RelPath}; use super::prepare::GitRepo; @@ -114,8 +114,9 @@ pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github( pub(crate) static PORTABLE_SIMD: CargoProject = CargoProject::new(&PORTABLE_SIMD_REPO.source_dir(), "portable_simd"); -pub(crate) static LIBCORE_TESTS: CargoProject = - CargoProject::new(&SYSROOT_SRC.join("library/core/tests"), "core_tests"); +pub(crate) static LIBCORE_TESTS_SRC: RelPath = RelPath::DOWNLOAD.join("coretests_src"); + +pub(crate) static LIBCORE_TESTS: CargoProject = CargoProject::new(&LIBCORE_TESTS_SRC, "core_tests"); const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ TestCase::custom("test.rust-random/rand", &|runner| { diff --git a/patches/0022-sysroot-Disable-not-compiling-tests.patch b/patches/0022-coretests-Disable-not-compiling-tests.patch similarity index 80% rename from patches/0022-sysroot-Disable-not-compiling-tests.patch rename to patches/0022-coretests-Disable-not-compiling-tests.patch index 4db56fa3bd2c7..6afa5c71fe51f 100644 --- a/patches/0022-sysroot-Disable-not-compiling-tests.patch +++ b/patches/0022-coretests-Disable-not-compiling-tests.patch @@ -13,14 +13,14 @@ Subject: [PATCH] [core] Disable not compiling tests 6 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 library/core/tests/Cargo.toml -diff --git a/library/core/tests/Cargo.toml b/library/core/tests/Cargo.toml +diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..46fd999 --- /dev/null -+++ b/library/core/tests/Cargo.toml ++++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] -+name = "core" ++name = "coretests" +version = "0.0.0" +edition = "2021" + @@ -31,10 +31,10 @@ index 0000000..46fd999 +[dependencies] +rand = { version = "0.8.5", default-features = false } +rand_xorshift = { version = "0.3.0", default-features = false } -diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs +diff --git a/lib.rs b/lib.rs index 42a26ae..5ac1042 100644 ---- a/library/core/tests/lib.rs -+++ b/library/core/tests/lib.rs +--- a/lib.rs ++++ b/lib.rs @@ -1,3 +1,4 @@ +#![cfg(test)] #![feature(alloc_layout_extra)] diff --git a/patches/0023-sysroot-Ignore-failing-tests.patch b/patches/0023-coretests-Ignore-failing-tests.patch similarity index 85% rename from patches/0023-sysroot-Ignore-failing-tests.patch rename to patches/0023-coretests-Ignore-failing-tests.patch index f3cd7ee77e26e..f2cb82751f082 100644 --- a/patches/0023-sysroot-Ignore-failing-tests.patch +++ b/patches/0023-coretests-Ignore-failing-tests.patch @@ -10,10 +10,10 @@ Subject: [PATCH] [core] Ignore failing tests library/core/tests/time.rs | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) -diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs +diff --git a/array.rs b/array.rs index 4bc44e9..8e3c7a4 100644 ---- a/library/core/tests/array.rs -+++ b/library/core/tests/array.rs +--- a/array.rs ++++ b/array.rs @@ -242,6 +242,7 @@ fn iterator_drops() { assert_eq!(i.get(), 5); } @@ -46,10 +46,10 @@ index 4bc44e9..8e3c7a4 100644 #[test] fn cell_allows_array_cycle() { -diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs +diff --git a/atomic.rs b/atomic.rs index 13b12db..96fe4b9 100644 ---- a/library/core/tests/atomic.rs -+++ b/library/core/tests/atomic.rs +--- a/atomic.rs ++++ b/atomic.rs @@ -185,6 +185,7 @@ fn ptr_bitops() { } diff --git a/patches/0027-coretests-128bit-atomic-operations.patch b/patches/0027-coretests-128bit-atomic-operations.patch new file mode 100644 index 0000000000000..1d5479beddee9 --- /dev/null +++ b/patches/0027-coretests-128bit-atomic-operations.patch @@ -0,0 +1,30 @@ +From ad7ffe71baba46865f2e65266ab025920dfdc20b Mon Sep 17 00:00:00 2001 +From: bjorn3 +Date: Thu, 18 Feb 2021 18:45:28 +0100 +Subject: [PATCH] Disable 128bit atomic operations + +Cranelift doesn't support them yet +--- + library/core/src/panic/unwind_safe.rs | 6 ----- + library/core/src/sync/atomic.rs | 38 --------------------------- + library/core/tests/atomic.rs | 4 --- + 4 files changed, 4 insertions(+), 50 deletions(-) + +diff --git a/atomic.rs b/atomic.rs +index b735957..ea728b6 100644 +--- a/atomic.rs ++++ b/atomic.rs +@@ -185,10 +185,6 @@ fn atomic_alignment() { + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "64")] + assert_eq!(align_of::(), size_of::()); +- #[cfg(target_has_atomic = "128")] +- assert_eq!(align_of::(), size_of::()); +- #[cfg(target_has_atomic = "128")] +- assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "ptr")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "ptr")] +-- +2.26.2.7.g19db9cfb68 + diff --git a/patches/0027-sysroot-128bit-atomic-operations.patch b/patches/0027-stdlib-128bit-atomic-operations.patch similarity index 83% rename from patches/0027-sysroot-128bit-atomic-operations.patch rename to patches/0027-stdlib-128bit-atomic-operations.patch index 77f437974c2d6..45f73f36b9317 100644 --- a/patches/0027-sysroot-128bit-atomic-operations.patch +++ b/patches/0027-stdlib-128bit-atomic-operations.patch @@ -85,21 +85,6 @@ index d9de37e..8293fce 100644 macro_rules! atomic_int_ptr_sized { ( $($target_pointer_width:literal $align:literal)* ) => { $( -diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs -index b735957..ea728b6 100644 ---- a/library/core/tests/atomic.rs -+++ b/library/core/tests/atomic.rs -@@ -185,10 +185,6 @@ fn atomic_alignment() { - assert_eq!(align_of::(), size_of::()); - #[cfg(target_has_atomic = "64")] - assert_eq!(align_of::(), size_of::()); -- #[cfg(target_has_atomic = "128")] -- assert_eq!(align_of::(), size_of::()); -- #[cfg(target_has_atomic = "128")] -- assert_eq!(align_of::(), size_of::()); - #[cfg(target_has_atomic = "ptr")] - assert_eq!(align_of::(), size_of::()); - #[cfg(target_has_atomic = "ptr")] -- 2.26.2.7.g19db9cfb68 diff --git a/patches/0028-sysroot-Disable-long-running-tests.patch b/patches/0028-coretests-Disable-long-running-tests.patch similarity index 89% rename from patches/0028-sysroot-Disable-long-running-tests.patch rename to patches/0028-coretests-Disable-long-running-tests.patch index d804a78cc1061..440177018f428 100644 --- a/patches/0028-sysroot-Disable-long-running-tests.patch +++ b/patches/0028-coretests-Disable-long-running-tests.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Disable long running tests library/core/tests/slice.rs | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs +diff --git a/slice.rs b/slice.rs index 8402833..84592e0 100644 ---- a/library/core/tests/slice.rs -+++ b/library/core/tests/slice.rs +--- a/slice.rs ++++ b/slice.rs @@ -1809,6 +1809,7 @@ fn sort_unstable() { assert!(v == [0xDEADBEEF]); } diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh index 35aa398449141..abb09775d2135 100644 --- a/scripts/setup_rust_fork.sh +++ b/scripts/setup_rust_fork.sh @@ -10,7 +10,7 @@ git fetch git checkout -- . git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')" -git -c user.name=Dummy -c user.email=dummy@example.com am ../patches/*-sysroot-*.patch +git -c user.name=Dummy -c user.email=dummy@example.com am ../patches/*-stdlib-*.patch git apply - < Date: Sun, 26 Feb 2023 13:36:16 +0100 Subject: [PATCH 058/124] Rustup to rustc 1.69.0-nightly (34e6673a0 2023-02-25) --- build_sysroot/Cargo.lock | 5 ++--- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index 586d47c1b72c7..c124635da5bf2 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -117,12 +117,11 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" dependencies = [ "compiler_builtins", - "libc", "rustc-std-workspace-alloc", "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index cfa3390b6d9ec..ed5ed02d432ab 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-25" +channel = "nightly-2023-02-26" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From aea3bd664137b1e04a2530cc47025f031c9b9974 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Feb 2023 13:01:47 +0000 Subject: [PATCH 059/124] Re-enable DataflowConstProp for standard library builds --- build_system/build_sysroot.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 4fb77c35c707c..76b602fe71963 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -242,8 +242,7 @@ fn build_clif_sysroot_for_triple( rustflags .push_str(&format!(" --sysroot={}", RTSTARTUP_SYSROOT.to_path(dirs).to_str().unwrap())); if channel == "release" { - // FIXME re-enable DataflowConstProp once rust-lang/rust#108166 is fixed - rustflags.push_str(" -Zmir-opt-level=3 -Zmir-enable-passes=-DataflowConstProp"); + rustflags.push_str(" -Zmir-opt-level=3"); } compiler.rustflags += &rustflags; let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs); From 7a864c8ef54ca810884b0a27d108a350c3e6b4d7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Feb 2023 14:04:45 +0000 Subject: [PATCH 060/124] Update test repo versions --- build_system/tests.rs | 6 ++++-- patches/0003-rand-Disable-rand-tests-on-mingw.patch | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index b55187aa3b4c9..5ce1786e25611 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -94,13 +94,15 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[ TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]), ]; +// FIXME(rust-random/rand#1293): Newer rand versions fail to test on Windows. Update once this is +// fixed. pub(crate) static RAND_REPO: GitRepo = - GitRepo::github("rust-random", "rand", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", "rand"); + GitRepo::github("rust-random", "rand", "50b9a447410860af8d6db9a208c3576886955874", "rand"); pub(crate) static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand"); pub(crate) static REGEX_REPO: GitRepo = - GitRepo::github("rust-lang", "regex", "341f207c1071f7290e3f228c710817c280c8dca1", "regex"); + GitRepo::github("rust-lang", "regex", "a9b2e02352db92ce1f6e5b7ecd41b8bbffbe161a", "regex"); pub(crate) static REGEX: CargoProject = CargoProject::new(®EX_REPO.source_dir(), "regex"); diff --git a/patches/0003-rand-Disable-rand-tests-on-mingw.patch b/patches/0003-rand-Disable-rand-tests-on-mingw.patch index d8775e2d022a0..eb452c5cd3772 100644 --- a/patches/0003-rand-Disable-rand-tests-on-mingw.patch +++ b/patches/0003-rand-Disable-rand-tests-on-mingw.patch @@ -19,8 +19,8 @@ index 217899e..9cedeb7 100644 + // This is broken on x86_64-pc-windows-gnu presumably due to a broken powf implementation + #[cfg_attr(all(target_os = "windows", target_env = "gnu"), ignore)] fn value_stability() { - fn test_samples>( - distr: D, zero: F, expected: &[F], + fn test_samples>( + distr: D, thresh: F, expected: &[F], diff --git a/rand_distr/tests/value_stability.rs b/rand_distr/tests/value_stability.rs index 192ba74..0101ace 100644 --- a/rand_distr/tests/value_stability.rs From 5e6cde150e4b09d97a204f697e65e9d53e0af96a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Feb 2023 14:27:45 +0000 Subject: [PATCH 061/124] Remove --cap-lint warn from regex test --- build_system/tests.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index 5ce1786e25611..3738b5319b0c5 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -153,18 +153,13 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ TestCase::custom("test.regex-shootout-regex-dna", &|runner| { REGEX.clean(&runner.dirs); - // newer aho_corasick versions throw a deprecation warning - let lint_rust_flags = format!("{} --cap-lints warn", runner.target_compiler.rustflags); - let mut build_cmd = REGEX.build(&runner.target_compiler, &runner.dirs); build_cmd.arg("--example").arg("shootout-regex-dna"); - build_cmd.env("RUSTFLAGS", lint_rust_flags.clone()); spawn_and_wait(build_cmd); if runner.is_native { let mut run_cmd = REGEX.run(&runner.target_compiler, &runner.dirs); run_cmd.arg("--example").arg("shootout-regex-dna"); - run_cmd.env("RUSTFLAGS", lint_rust_flags); let input = fs::read_to_string( REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-input.txt"), @@ -197,9 +192,6 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ TestCase::custom("test.regex", &|runner| { REGEX.clean(&runner.dirs); - // newer aho_corasick versions throw a deprecation warning - let lint_rust_flags = format!("{} --cap-lints warn", runner.target_compiler.rustflags); - if runner.is_native { let mut run_cmd = REGEX.test(&runner.target_compiler, &runner.dirs); run_cmd.args([ @@ -211,13 +203,11 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ "-Zunstable-options", "-q", ]); - run_cmd.env("RUSTFLAGS", lint_rust_flags); spawn_and_wait(run_cmd); } else { eprintln!("Cross-Compiling: Not running tests"); let mut build_cmd = REGEX.build(&runner.target_compiler, &runner.dirs); build_cmd.arg("--tests"); - build_cmd.env("RUSTFLAGS", lint_rust_flags.clone()); spawn_and_wait(build_cmd); } }), From 19ed2139a3250f974312becfd0fe3ef609cf68bf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Feb 2023 14:28:22 +0000 Subject: [PATCH 062/124] Remove no longer necessary code removing "[codegen mono items]" from test output --- build_system/tests.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index 3738b5319b0c5..ff958dcdc697d 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -171,13 +171,6 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ .unwrap(); let output = spawn_and_wait_with_input(run_cmd, input); - // Make sure `[codegen mono items] start` doesn't poison the diff - let output = output - .lines() - .filter(|line| !line.contains("codegen mono items")) - .chain(Some("")) // This just adds the trailing newline - .collect::>() - .join("\r\n"); let output_matches = expected.lines().eq(output.lines()); if !output_matches { From b193419ec7550d1d4262e8bc4448f4bd55fc9f20 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Feb 2023 16:50:08 +0000 Subject: [PATCH 063/124] Allow multiple threads and panicking tests when testing regex I guess this was a leftover from very early in the development of cg_clif. Allowing multiple threads significantly improves performance, while panicking tests can run now thanks to -Zpanic-abort-tests. --- build_system/tests.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index ff958dcdc697d..ba0a98e737131 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -187,15 +187,7 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ if runner.is_native { let mut run_cmd = REGEX.test(&runner.target_compiler, &runner.dirs); - run_cmd.args([ - "--tests", - "--", - "--exclude-should-panic", - "--test-threads", - "1", - "-Zunstable-options", - "-q", - ]); + run_cmd.args(["--tests", "--", "-q"]); spawn_and_wait(run_cmd); } else { eprintln!("Cross-Compiling: Not running tests"); From c615e9248aed8ce6bbb5ae73d38595bde3457bae Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Feb 2023 17:35:53 +0000 Subject: [PATCH 064/124] Run tests for all crates in the regex workspace --- build_system/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index ba0a98e737131..956a61ceaecc8 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -187,7 +187,7 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ if runner.is_native { let mut run_cmd = REGEX.test(&runner.target_compiler, &runner.dirs); - run_cmd.args(["--tests", "--", "-q"]); + run_cmd.args(["--workspace", "--", "-q"]); spawn_and_wait(run_cmd); } else { eprintln!("Cross-Compiling: Not running tests"); From b88e129915b2b623331997b4234cdfeb367b45c7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Feb 2023 17:37:29 +0000 Subject: [PATCH 065/124] Avoid a duplicate "[TEST] rust-random/rand" --- build_system/tests.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index 956a61ceaecc8..261948a697137 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -125,12 +125,11 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ RAND.clean(&runner.dirs); if runner.is_native { - eprintln!("[TEST] rust-random/rand"); let mut test_cmd = RAND.test(&runner.target_compiler, &runner.dirs); test_cmd.arg("--workspace").arg("--").arg("-q"); spawn_and_wait(test_cmd); } else { - eprintln!("[AOT] rust-random/rand"); + eprintln!("Cross-Compiling: Not running tests"); let mut build_cmd = RAND.build(&runner.target_compiler, &runner.dirs); build_cmd.arg("--workspace").arg("--tests"); spawn_and_wait(build_cmd); From 1b57cb6762a36c2f7823e87829c18b2ccd00f6de Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sun, 26 Feb 2023 21:50:19 +0000 Subject: [PATCH 066/124] Unify all validity check intrinsics Also merges the inhabitedness check into the query to further unify the code paths. --- src/intrinsics/mod.rs | 80 +++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 49 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index f00e932107058..e74aabf2fcb0d 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -22,7 +22,7 @@ pub(crate) use cpuid::codegen_cpuid_call; pub(crate) use llvm::codegen_llvm_intrinsic_call; use rustc_middle::ty; -use rustc_middle::ty::layout::{HasParamEnv, InitKind}; +use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::SubstsRef; use rustc_span::symbol::{kw, sym, Symbol}; @@ -628,57 +628,39 @@ fn codegen_regular_intrinsic_call<'tcx>( intrinsic_args!(fx, args => (); intrinsic); let ty = substs.type_at(0); - let layout = fx.layout_of(ty); - if layout.abi.is_uninhabited() { - with_no_trimmed_paths!({ - crate::base::codegen_panic_nounwind( - fx, - &format!("attempted to instantiate uninhabited type `{}`", layout.ty), - source_info, - ) - }); - return; - } - if intrinsic == sym::assert_zero_valid - && !fx - .tcx - .check_validity_of_init((InitKind::Zero, fx.param_env().and(ty))) - .expect("expected to have layout during codegen") - { - with_no_trimmed_paths!({ - crate::base::codegen_panic_nounwind( - fx, - &format!( - "attempted to zero-initialize type `{}`, which is invalid", - layout.ty - ), - source_info, - ); - }); - return; - } + let requirement = ValidityRequirement::from_intrinsic(intrinsic); - if intrinsic == sym::assert_mem_uninitialized_valid - && !fx + if let Some(requirement) = requirement { + let do_panic = !fx .tcx - .check_validity_of_init(( - InitKind::UninitMitigated0x01Fill, - fx.param_env().and(ty), - )) - .expect("expected to have layout during codegen") - { - with_no_trimmed_paths!({ - crate::base::codegen_panic_nounwind( - fx, - &format!( - "attempted to leave type `{}` uninitialized, which is invalid", - layout.ty - ), - source_info, - ) - }); - return; + .check_validity_requirement((requirement, fx.param_env().and(ty))) + .expect("expect to have layout during codegen"); + + if do_panic { + let layout = fx.layout_of(ty); + + with_no_trimmed_paths!({ + crate::base::codegen_panic_nounwind( + fx, + &if layout.abi.is_uninhabited() { + format!("attempted to instantiate uninhabited type `{}`", layout.ty) + } else if requirement == ValidityRequirement::Zero { + format!( + "attempted to zero-initialize type `{}`, which is invalid", + layout.ty + ) + } else { + format!( + "attempted to leave type `{}` uninitialized, which is invalid", + layout.ty + ) + }, + source_info, + ) + }); + return; + } } } From dd582bd7db1645b643133ff5e3133e55de15d841 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 13 Feb 2023 21:08:15 +0000 Subject: [PATCH 067/124] Implement checked Shl/Shr at MIR building. --- compiler/rustc_codegen_cranelift/src/num.rs | 23 ----- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 11 --- .../src/transform/validate.rs | 9 -- compiler/rustc_middle/src/ty/util.rs | 24 +++--- .../src/build/expr/as_rvalue.rs | 85 ++++++++++++++----- .../mir-opt/issue_101973.inner.ConstProp.diff | 58 +++++++------ tests/ui/consts/offset_from_ub.stderr | 6 +- 7 files changed, 109 insertions(+), 107 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index c058ece96d8e3..fbecdab158c8e 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -170,14 +170,6 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, ) -> CValue<'tcx> { - if bin_op != BinOp::Shl && bin_op != BinOp::Shr { - assert_eq!( - in_lhs.layout().ty, - in_rhs.layout().ty, - "checked int binop requires lhs and rhs of same type" - ); - } - let lhs = in_lhs.load_scalar(fx); let rhs = in_rhs.load_scalar(fx); @@ -271,21 +263,6 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( _ => unreachable!("invalid non-integer type {}", ty), } } - BinOp::Shl => { - let val = fx.bcx.ins().ishl(lhs, rhs); - let ty = fx.bcx.func.dfg.value_type(val); - let max_shift = i64::from(ty.bits()) - 1; - let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift); - (val, has_overflow) - } - BinOp::Shr => { - let val = - if !signed { fx.bcx.ins().ushr(lhs, rhs) } else { fx.bcx.ins().sshr(lhs, rhs) }; - let ty = fx.bcx.func.dfg.value_type(val); - let max_shift = i64::from(ty.bits()) - 1; - let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift); - (val, has_overflow) - } _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs), }; diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 3d856986fb4f7..13c4fa132d877 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -663,17 +663,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; bx.checked_binop(oop, input_ty, lhs, rhs) } - mir::BinOp::Shl | mir::BinOp::Shr => { - let lhs_llty = bx.cx().val_ty(lhs); - let rhs_llty = bx.cx().val_ty(rhs); - let invert_mask = common::shift_mask_val(bx, lhs_llty, rhs_llty, true); - let outer_bits = bx.and(rhs, invert_mask); - - let of = bx.icmp(IntPredicate::IntNE, outer_bits, bx.cx().const_null(rhs_llty)); - let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty); - - (val, of) - } _ => bug!("Operator `{:?}` is not a checkable operator", op), }; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 068491646f47b..785dde93e31ac 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -553,15 +553,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } - Shl | Shr => { - for x in [a, b] { - check_kinds!( - x, - "Cannot perform checked shift on non-integer type {:?}", - ty::Uint(..) | ty::Int(..) - ) - } - } _ => self.fail(location, format!("There is no checked version of {:?}", op)), } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 90270e0ee9da5..754b6efd692d8 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -59,22 +59,13 @@ impl<'tcx> fmt::Display for Discr<'tcx> { } } -fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) { - let (int, signed) = match *ty.kind() { - ty::Int(ity) => (Integer::from_int_ty(&tcx, ity), true), - ty::Uint(uty) => (Integer::from_uint_ty(&tcx, uty), false), - _ => bug!("non integer discriminant"), - }; - (int.size(), signed) -} - impl<'tcx> Discr<'tcx> { /// Adds `1` to the value and wraps around if the maximum for the type is reached. pub fn wrap_incr(self, tcx: TyCtxt<'tcx>) -> Self { self.checked_add(tcx, 1).0 } pub fn checked_add(self, tcx: TyCtxt<'tcx>, n: u128) -> (Self, bool) { - let (size, signed) = int_size_and_signed(tcx, self.ty); + let (size, signed) = self.ty.int_size_and_signed(tcx); let (val, oflo) = if signed { let min = size.signed_int_min(); let max = size.signed_int_max(); @@ -922,12 +913,21 @@ impl<'tcx> TypeFolder> for OpaqueTypeExpander<'tcx> { } impl<'tcx> Ty<'tcx> { + pub fn int_size_and_signed(self, tcx: TyCtxt<'tcx>) -> (Size, bool) { + let (int, signed) = match *self.kind() { + ty::Int(ity) => (Integer::from_int_ty(&tcx, ity), true), + ty::Uint(uty) => (Integer::from_uint_ty(&tcx, uty), false), + _ => bug!("non integer discriminant"), + }; + (int.size(), signed) + } + /// Returns the maximum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option> { let val = match self.kind() { ty::Int(_) | ty::Uint(_) => { - let (size, signed) = int_size_and_signed(tcx, self); + let (size, signed) = self.int_size_and_signed(tcx); let val = if signed { size.signed_int_max() as u128 } else { size.unsigned_int_max() }; Some(val) @@ -948,7 +948,7 @@ impl<'tcx> Ty<'tcx> { pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option> { let val = match self.kind() { ty::Int(_) | ty::Uint(_) => { - let (size, signed) = int_size_and_signed(tcx, self); + let (size, signed) = self.int_size_and_signed(tcx); let val = if signed { size.truncate(size.signed_int_min() as u128) } else { 0 }; Some(val) } diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index a4e48c1545d6c..259e0f8f75c1b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -9,6 +9,7 @@ use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary}; use rustc_hir::lang_items::LangItem; use rustc_middle::middle::region; +use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::AssertKind; use rustc_middle::mir::Place; use rustc_middle::mir::*; @@ -519,30 +520,68 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) -> BlockAnd> { let source_info = self.source_info(span); let bool_ty = self.tcx.types.bool; - if self.check_overflow && op.is_checkable() && ty.is_integral() { - let result_tup = self.tcx.mk_tup(&[ty, bool_ty]); - let result_value = self.temp(result_tup, span); + let rvalue = match op { + BinOp::Add | BinOp::Sub | BinOp::Mul if self.check_overflow && ty.is_integral() => { + let result_tup = self.tcx.mk_tup(&[ty, bool_ty]); + let result_value = self.temp(result_tup, span); - self.cfg.push_assign( - block, - source_info, - result_value, - Rvalue::CheckedBinaryOp(op, Box::new((lhs.to_copy(), rhs.to_copy()))), - ); - let val_fld = Field::new(0); - let of_fld = Field::new(1); + self.cfg.push_assign( + block, + source_info, + result_value, + Rvalue::CheckedBinaryOp(op, Box::new((lhs.to_copy(), rhs.to_copy()))), + ); + let val_fld = Field::new(0); + let of_fld = Field::new(1); + + let tcx = self.tcx; + let val = tcx.mk_place_field(result_value, val_fld, ty); + let of = tcx.mk_place_field(result_value, of_fld, bool_ty); - let tcx = self.tcx; - let val = tcx.mk_place_field(result_value, val_fld, ty); - let of = tcx.mk_place_field(result_value, of_fld, bool_ty); + let err = AssertKind::Overflow(op, lhs, rhs); + block = self.assert(block, Operand::Move(of), false, err, span); - let err = AssertKind::Overflow(op, lhs, rhs); + Rvalue::Use(Operand::Move(val)) + } + BinOp::Shl | BinOp::Shr if self.check_overflow && ty.is_integral() => { + // Consider that the shift overflows if `rhs < 0` or `rhs >= bits`. + // This can be encoded as a single operation as `(rhs & -bits) != 0`. + let (size, _) = ty.int_size_and_signed(self.tcx); + let bits = size.bits(); + debug_assert!(bits.is_power_of_two()); + let mask = !((bits - 1) as u128); + + let rhs_ty = rhs.ty(&self.local_decls, self.tcx); + let (rhs_size, _) = rhs_ty.int_size_and_signed(self.tcx); + let mask = Operand::const_from_scalar( + self.tcx, + rhs_ty, + Scalar::from_uint(rhs_size.truncate(mask), rhs_size), + span, + ); - block = self.assert(block, Operand::Move(of), false, err, span); + let outer_bits = self.temp(rhs_ty, span); + self.cfg.push_assign( + block, + source_info, + outer_bits, + Rvalue::BinaryOp(BinOp::BitAnd, Box::new((rhs.to_copy(), mask))), + ); - block.and(Rvalue::Use(Operand::Move(val))) - } else { - if ty.is_integral() && (op == BinOp::Div || op == BinOp::Rem) { + let overflows = self.temp(bool_ty, span); + let zero = self.zero_literal(span, rhs_ty); + self.cfg.push_assign( + block, + source_info, + overflows, + Rvalue::BinaryOp(BinOp::Ne, Box::new((Operand::Move(outer_bits), zero))), + ); + + let overflow_err = AssertKind::Overflow(op, lhs.to_copy(), rhs.to_copy()); + block = self.assert(block, Operand::Move(overflows), false, overflow_err, span); + Rvalue::BinaryOp(op, Box::new((lhs, rhs))) + } + BinOp::Div | BinOp::Rem if ty.is_integral() => { // Checking division and remainder is more complex, since we 1. always check // and 2. there are two possible failure cases, divide-by-zero and overflow. @@ -601,10 +640,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block = self.assert(block, Operand::Move(of), false, overflow_err, span); } - } - block.and(Rvalue::BinaryOp(op, Box::new((lhs, rhs)))) - } + Rvalue::BinaryOp(op, Box::new((lhs, rhs))) + } + _ => Rvalue::BinaryOp(op, Box::new((lhs, rhs))), + }; + block.and(rvalue) } fn build_zero_repeat( diff --git a/tests/mir-opt/issue_101973.inner.ConstProp.diff b/tests/mir-opt/issue_101973.inner.ConstProp.diff index 6db8e4d266472..fb0b3866e696b 100644 --- a/tests/mir-opt/issue_101973.inner.ConstProp.diff +++ b/tests/mir-opt/issue_101973.inner.ConstProp.diff @@ -12,13 +12,14 @@ let mut _7: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 let mut _8: u32; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 let mut _9: u32; // in scope 0 at $DIR/issue_101973.rs:+1:33: +1:39 - let mut _10: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 - let mut _11: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + let mut _10: i32; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + let mut _11: bool; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + let mut _12: i32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + let mut _13: bool; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 scope 1 (inlined imm8) { // at $DIR/issue_101973.rs:14:5: 14:17 debug x => _1; // in scope 1 at $DIR/issue_101973.rs:5:13: 5:14 - let mut _12: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:27 - let mut _13: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20 - let mut _14: (u32, bool); // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20 + let mut _14: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:27 + let mut _15: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20 scope 2 { debug out => _4; // in scope 2 at $DIR/issue_101973.rs:6:9: 6:16 } @@ -32,43 +33,46 @@ StorageLive(_2); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 StorageLive(_3); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:58 StorageLive(_4); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:17 - StorageLive(_12); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27 - StorageLive(_13); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 - _14 = CheckedShr(_1, const 0_i32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 - assert(!move (_14.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + StorageLive(_14); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27 + StorageLive(_15); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + _15 = Shr(_1, const 0_i32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 + _14 = BitAnd(move _15, const 255_u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27 + StorageDead(_15); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 + _4 = BitOr(const 0_u32, move _14); // scope 2 at $DIR/issue_101973.rs:7:5: 7:27 + StorageDead(_14); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 + StorageLive(_6); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + StorageLive(_7); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 + StorageLive(_8); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 +- _10 = BitAnd(const 8_i32, const -32_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 +- _11 = Ne(move _10, const 0_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 +- assert(!move _11, "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 ++ _10 = const 0_i32; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 ++ _11 = const false; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 ++ assert(!const false, "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 } bb1: { - _8 = move (_10.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 + _8 = Shr(_1, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 StorageDead(_8); // scope 0 at $DIR/issue_101973.rs:+1:51: +1:52 - _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 - assert(!move (_11.1: bool), "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 +- _12 = BitAnd(const 1_i32, const -32_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 +- _13 = Ne(move _12, const 0_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 +- assert(!move _13, "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 ++ _12 = const 0_i32; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 ++ _13 = const false; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 ++ assert(!const false, "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 } bb2: { - _6 = move (_11.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 + _6 = Shl(move _7, const 1_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 StorageDead(_7); // scope 0 at $DIR/issue_101973.rs:+1:56: +1:57 - _3 = rotate_right::(_4, _6) -> bb4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _3 = rotate_right::(_4, _6) -> bb3; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // + literal: Const { ty: extern "rust-intrinsic" fn(u32, u32) -> u32 {rotate_right::}, val: Value() } } bb3: { - _13 = move (_14.0: u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 - _12 = BitAnd(move _13, const 255_u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27 - StorageDead(_13); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 - _4 = BitOr(const 0_u32, move _12); // scope 2 at $DIR/issue_101973.rs:7:5: 7:27 - StorageDead(_12); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 - StorageLive(_6); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 - StorageLive(_7); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 - StorageLive(_8); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 - _10 = CheckedShr(_1, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 - assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 - } - - bb4: { StorageDead(_6); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 StorageDead(_4); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 _2 = move _3 as i32 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr index fff4729689f54..6530084a5857d 100644 --- a/tests/ui/consts/offset_from_ub.stderr +++ b/tests/ui/consts/offset_from_ub.stderr @@ -39,19 +39,19 @@ error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:53:14 | LL | unsafe { ptr_offset_from(end_ptr, start_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc18 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc17 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:62:14 | LL | unsafe { ptr_offset_from(start_ptr, end_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc21 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc20 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:70:14 | LL | unsafe { ptr_offset_from(end_ptr, end_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc24 has size 4, so pointer at offset 10 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc23 has size 4, so pointer at offset 10 is out-of-bounds error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:79:14 From 0422f44dc475f60b9e9dbf5e0015abf9dcdffe44 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 21 Feb 2023 18:53:30 +0000 Subject: [PATCH 068/124] Update MIR doc. --- compiler/rustc_middle/src/mir/syntax.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index ae09562a85e98..2a722c4c72e30 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1112,10 +1112,6 @@ pub enum Rvalue<'tcx> { /// For addition, subtraction, and multiplication on integers the error condition is set when /// the infinite precision result would be unequal to the actual result. /// - /// For shift operations on integers the error condition is set when the value of right-hand - /// side is greater than or equal to the number of bits in the type of the left-hand side, or - /// when the value of right-hand side is negative. - /// /// Other combinations of types and operators are unsupported. CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>), From 162365e3d64786dcd6deca7c08285e9c16aa26cb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 28 Feb 2023 14:36:44 +0000 Subject: [PATCH 069/124] Fix loading of dylibs not in the search path in jit mode Reported in #1249 --- src/driver/jit.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 8b5a2da2c5944..f6a48e3257bc2 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -311,7 +311,11 @@ fn dep_symbol_lookup_fn( .find(|(crate_type, _data)| *crate_type == rustc_session::config::CrateType::Executable) .unwrap() .1; - for &cnum in &crate_info.used_crates { + // `used_crates` is in reverse postorder in terms of dependencies. Reverse the order here to + // get a postorder which ensures that all dependencies of a dylib are loaded before the dylib + // itself. This helps the dynamic linker to find dylibs not in the regular dynamic library + // search path. + for &cnum in crate_info.used_crates.iter().rev() { let src = &crate_info.used_crate_source[&cnum]; match data[cnum.as_usize() - 1] { Linkage::NotLinked | Linkage::IncludedFromDylib => {} From 7bf863653b6c06cfd987f8b5014795aed58da0ec Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 4 Mar 2023 12:46:45 +0100 Subject: [PATCH 070/124] Rustup to rustc 1.69.0-nightly (44cfafe2f 2023-03-03) --- build_sysroot/Cargo.lock | 2 -- rust-toolchain | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index c124635da5bf2..5f25d7e9ad473 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -281,10 +281,8 @@ dependencies = [ name = "test" version = "0.0.0" dependencies = [ - "cfg-if", "core", "getopts", - "libc", "panic_abort", "panic_unwind", "proc_macro", diff --git a/rust-toolchain b/rust-toolchain index ed5ed02d432ab..98dd946c92ea5 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-26" +channel = "nightly-2023-03-04" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 4be2be22450a8fd70f1e5e0d66fe59fb45412ef0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 4 Mar 2023 12:48:34 +0100 Subject: [PATCH 071/124] Rustfmt --- src/intrinsics/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 5bb3d850659ce..85656b8b5f3d8 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -652,7 +652,10 @@ fn codegen_regular_intrinsic_call<'tcx>( // Use this error even for the other intrinsics as it is more precise. format!("attempted to instantiate uninhabited type `{}`", ty) } else if intrinsic == sym::assert_zero_valid { - format!("attempted to zero-initialize type `{}`, which is invalid", ty) + format!( + "attempted to zero-initialize type `{}`, which is invalid", + ty + ) } else { format!( "attempted to leave type `{}` uninitialized, which is invalid", From 906b00e11107a7070fc10a6f6dc8bbbb201cfc2e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 4 Mar 2023 12:59:27 +0000 Subject: [PATCH 072/124] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index a82dd4474048a..7952a2c86aed8 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -21,6 +21,7 @@ done git checkout -- tests/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed git checkout -- tests/ui/proc-macro/pretty-print-hack/ +rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR # missing features # ================ From c0afabbb424dfe0c2ad5135853ad7f5b24f561b1 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Thu, 2 Mar 2023 18:00:22 +0000 Subject: [PATCH 073/124] Support for Fuchsia RISC-V target Fuchsia is in the process of implementing the RISC-V support. This change implements the minimal Rust compiler support. The support for building runtime libraries will be implemented in follow up changes once Fuchsia SDK has the RISC-V support. --- compiler/rustc_target/src/spec/mod.rs | 1 + .../src/spec/riscv64gc_unknown_fuchsia.rs | 19 +++++++++++++++++++ src/doc/rustc/src/platform-support.md | 1 + 3 files changed, 21 insertions(+) create mode 100644 compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 0d86a3032a659..f3304e9142920 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1115,6 +1115,7 @@ supported_targets! { // FIXME(#106649): Remove aarch64-fuchsia in favor of aarch64-unknown-fuchsia ("aarch64-fuchsia", aarch64_fuchsia), ("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia), + ("riscv64gc-unknown-fuchsia", riscv64gc_unknown_fuchsia), // FIXME(#106649): Remove x86_64-fuchsia in favor of x86_64-unknown-fuchsia ("x86_64-fuchsia", x86_64_fuchsia), ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia), diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs new file mode 100644 index 0000000000000..ab7c08958fa88 --- /dev/null +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs @@ -0,0 +1,19 @@ +use crate::spec::{CodeModel, SanitizerSet, Target, TargetOptions}; + +pub fn target() -> Target { + Target { + llvm_target: "riscv64gc-unknown-fuchsia".into(), + pointer_width: 64, + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), + arch: "riscv64".into(), + options: TargetOptions { + code_model: Some(CodeModel::Medium), + cpu: "generic-rv64".into(), + features: "+m,+a,+f,+d,+c".into(), + llvm_abiname: "lp64d".into(), + max_atomic_width: Some(64), + supported_sanitizers: SanitizerSet::SHADOWCALLSTACK, + ..super::fuchsia_base::opts() + }, + } +} diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 9eafa27e2b7c8..2d74a2240969c 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -295,6 +295,7 @@ target | std | host | notes [`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) `riscv32imc-esp-espidf` | ✓ | | RISC-V ESP-IDF `riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD +`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia `riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.0) [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 `s390x-unknown-linux-musl` | | | S390x Linux (kernel 3.2, MUSL) From 1ed6b05145a4729b5812e63aa15c0ccc7ec6495e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 5 Mar 2023 19:50:21 +0000 Subject: [PATCH 074/124] Remove copy_nonoverlapping intrinsic definition It has been getting lowered to a dedicated MIR statement for a while --- src/intrinsics/mod.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 85656b8b5f3d8..88f37b19529d5 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -388,7 +388,7 @@ fn codegen_regular_intrinsic_call<'tcx>( fx.bcx.ins().debugtrap(); } - sym::copy | sym::copy_nonoverlapping => { + sym::copy => { intrinsic_args!(fx, args => (src, dst, count); intrinsic); let src = src.load_scalar(fx); let dst = dst.load_scalar(fx); @@ -400,13 +400,8 @@ fn codegen_regular_intrinsic_call<'tcx>( let byte_amount = if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count }; - if intrinsic == sym::copy_nonoverlapping { - // FIXME emit_small_memcpy - fx.bcx.call_memcpy(fx.target_config, dst, src, byte_amount); - } else { - // FIXME emit_small_memmove - fx.bcx.call_memmove(fx.target_config, dst, src, byte_amount); - } + // FIXME emit_small_memmove + fx.bcx.call_memmove(fx.target_config, dst, src, byte_amount); } sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => { // NOTE: the volatile variants have src and dst swapped From bd84d88cd1174025720b5053d78e58fdd0524661 Mon Sep 17 00:00:00 2001 From: Giacomo Pasini Date: Sun, 5 Mar 2023 21:02:14 +0100 Subject: [PATCH 075/124] Remove DropAndReplace terminator PR 107844 made DropAndReplace unused, let's remove it completely from the codebase. --- src/base.rs | 1 - src/constant.rs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index 7f857528c7c5c..cb0e272cedaba 100644 --- a/src/base.rs +++ b/src/base.rs @@ -499,7 +499,6 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { TerminatorKind::Yield { .. } | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } - | TerminatorKind::DropAndReplace { .. } | TerminatorKind::GeneratorDrop => { bug!("shouldn't exist at codegen {:?}", bb_data.terminator()); } diff --git a/src/constant.rs b/src/constant.rs index 49c4f1aaaefc6..1930db72ead44 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -543,8 +543,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( | TerminatorKind::Unreachable | TerminatorKind::Drop { .. } | TerminatorKind::Assert { .. } => {} - TerminatorKind::DropAndReplace { .. } - | TerminatorKind::Yield { .. } + TerminatorKind::Yield { .. } | TerminatorKind::GeneratorDrop | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } => unreachable!(), From 22237ed22526c9a58cdfb3d0c3d91c3700bbaf4c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 8 Mar 2023 20:56:50 +0100 Subject: [PATCH 076/124] Update Cranelift to 0.93.1 This fixes a potential miscompilation --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4762d6dee158a..157ef4bf3892e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,18 +57,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b18cf92869a6ae85cde3af4bc4beb6154efa8adef03b18db2ad413d5bce3a2" +checksum = "a7379abaacee0f14abf3204a7606118f0465785252169d186337bcb75030815a" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567d9f6e919bac076f39b902a072686eaf9e6d015baa34d10a61b85105b7af59" +checksum = "9489fa336927df749631f1008007ced2871068544f40a202ce6d93fbf2366a7b" dependencies = [ "arrayvec", "bumpalo", @@ -87,24 +87,24 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e72b2d5ec8917b2971fe83850187373d0a186db4748a7c23a5f48691b8d92bb" +checksum = "05bbb67da91ec721ed57cef2f7c5ef7728e1cd9bde9ffd3ef8601022e73e3239" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3461c0e0c2ebbeb92533aacb27e219289f60dc84134ef34fbf2d77c9eddf07ef" +checksum = "418ecb2f36032f6665dc1a5e2060a143dbab41d83b784882e97710e890a7a16d" [[package]] name = "cranelift-entity" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af684f7f7b01427b1942c7102673322a51b9d6f261e9663dc5e5595786775531" +checksum = "7cf583f7b093f291005f9fb1323e2c37f6ee4c7909e39ce016b2e8360d461705" [[package]] name = "cranelift-frontend" @@ -120,9 +120,9 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.93.0" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef4f8f3984d772c199a48896d2fb766f96301bf71b371e03a2b99f4f3b7b931" +checksum = "649782a39ce99798dd6b4029e2bb318a2fbeaade1b4fa25330763c10c65bc358" [[package]] name = "cranelift-jit" From 95bcca85ff9a07e70f160e4e48a67d2e70b7c207 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Fri, 27 Jan 2023 17:22:05 +0300 Subject: [PATCH 077/124] remove obsolete `givens` from regionck --- .../src/check/compare_impl_item.rs | 5 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- .../src/impl_wf_check/min_specialization.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 9 +--- .../src/infer/canonical/query_response.rs | 4 +- .../src/infer/lexical_region_resolve/mod.rs | 47 +------------------ compiler/rustc_infer/src/infer/mod.rs | 4 -- .../rustc_infer/src/infer/outlives/env.rs | 46 +++++++----------- .../infer/region_constraints/leak_check.rs | 3 -- .../src/infer/region_constraints/mod.rs | 44 ++--------------- .../src/traits/coherence.rs | 1 - .../rustc_trait_selection/src/traits/misc.rs | 1 - 12 files changed, 26 insertions(+), 144 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 5adc7a8732373..f14fb200bb0ae 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -330,7 +330,6 @@ fn compare_method_predicate_entailment<'tcx>( // lifetime parameters. let outlives_env = OutlivesEnvironment::with_bounds( param_env, - Some(infcx), infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys.clone()), ); infcx.process_registered_region_obligations( @@ -728,7 +727,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // lifetime parameters. let outlives_environment = OutlivesEnvironment::with_bounds( param_env, - Some(infcx), infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys), ); infcx @@ -2051,8 +2049,7 @@ pub(super) fn check_type_bounds<'tcx>( // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, assumed_wf_types); - let outlives_environment = - OutlivesEnvironment::with_bounds(param_env, Some(&infcx), implied_bounds); + let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds); infcx.err_ctxt().check_region_obligations_and_report_errors( impl_ty.def_id.expect_local(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 4cccdf30c5fa6..8d9f87f89dc0a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -115,8 +115,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( return; } - let outlives_environment = - OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds); + let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds); let _ = infcx .err_ctxt() @@ -676,7 +675,6 @@ fn resolve_regions_with_wf_tys<'tcx>( let infcx = tcx.infer_ctxt().build(); let outlives_environment = OutlivesEnvironment::with_bounds( param_env, - Some(&infcx), infcx.implied_bounds_tys(param_env, id, wf_tys.clone()), ); let region_bound_pairs = outlives_environment.region_bound_pairs(); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index daa5d15704d87..46a2796b3c60a 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -179,7 +179,7 @@ fn get_impl_substs( } let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types); - let outlives_env = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds); + let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); let _ = infcx.err_ctxt().check_region_obligations_and_report_errors(impl1_def_id, &outlives_env); let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index c36c75e444368..11ff65d0c373a 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -238,15 +238,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Note that there are two tests to check that this remains true // (`regions-reassign-{match,let}-bound-pointer.rs`). // - // 2. Things go horribly wrong if we use subtype. The reason for - // THIS is a fairly subtle case involving bound regions. See the - // `givens` field in `region_constraints`, as well as the test + // 2. An outdated issue related to the old HIR borrowck. See the test // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`, - // for details. Short version is that we must sometimes detect - // relationships between specific region variables and regions - // bound in a closure signature, and that detection gets thrown - // off when we substitute fresh region variables here to enable - // subtyping. } /// Compute the new expected type and default binding mode from the old ones diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 436d29c2449e4..90e89a187822d 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -636,11 +636,9 @@ pub fn make_query_region_constraints<'tcx>( outlives_obligations: impl Iterator, ty::Region<'tcx>, ConstraintCategory<'tcx>)>, region_constraints: &RegionConstraintData<'tcx>, ) -> QueryRegionConstraints<'tcx> { - let RegionConstraintData { constraints, verifys, givens, member_constraints } = - region_constraints; + let RegionConstraintData { constraints, verifys, member_constraints } = region_constraints; assert!(verifys.is_empty()); - assert!(givens.is_empty()); debug!(?constraints); diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 2c480355085ef..cf657756ff534 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; use rustc_data_structures::intern::Interned; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::PlaceholderRegion; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -132,7 +132,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } let graph = self.construct_graph(); - self.expand_givens(&graph); self.expansion(&mut var_data); self.collect_errors(&mut var_data, errors); self.collect_var_errors(&var_data, &graph, errors); @@ -164,38 +163,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } - fn expand_givens(&mut self, graph: &RegionGraph<'_>) { - // Givens are a kind of horrible hack to account for - // constraints like 'c <= '0 that are known to hold due to - // closure signatures (see the comment above on the `givens` - // field). They should go away. But until they do, the role - // of this fn is to account for the transitive nature: - // - // Given 'c <= '0 - // and '0 <= '1 - // then 'c <= '1 - - let seeds: Vec<_> = self.data.givens.iter().cloned().collect(); - for (r, vid) in seeds { - // While all things transitively reachable in the graph - // from the variable (`'0` in the example above). - let seed_index = NodeIndex(vid.index() as usize); - for succ_index in graph.depth_traverse(seed_index, OUTGOING) { - let succ_index = succ_index.0; - - // The first N nodes correspond to the region - // variables. Other nodes correspond to constant - // regions. - if succ_index < self.num_vars() { - let succ_vid = RegionVid::new(succ_index); - - // Add `'c <= '1`. - self.data.givens.insert((r, succ_vid)); - } - } - } - } - /// Gets the LUb of a given region and the empty region fn lub_empty(&self, a_region: Region<'tcx>) -> Result, PlaceholderRegion> { match *a_region { @@ -362,18 +329,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ) -> bool { debug!("expand_node({:?}, {:?} == {:?})", a_region, b_vid, b_data); - match *a_region { - // Check if this relationship is implied by a given. - ty::ReEarlyBound(_) | ty::ReFree(_) => { - if self.data.givens.contains(&(a_region, b_vid)) { - debug!("given"); - return false; - } - } - - _ => {} - } - match *b_data { VarValue::Empty(empty_ui) => { let lub = match self.lub_empty(a_region) { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index fb067e7ac2135..1b49843822ed7 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -855,10 +855,6 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot) } - pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) { - self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); - } - pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool where T: at::ToTrace<'tcx>, diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index 24e3c34dd94fc..95f8f05ab6098 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -1,9 +1,9 @@ use crate::infer::free_regions::FreeRegionMap; -use crate::infer::{GenericKind, InferCtxt}; +use crate::infer::GenericKind; use crate::traits::query::OutlivesBound; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::transitive_relation::TransitiveRelationBuilder; -use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region}; +use rustc_middle::ty::{self, Region}; use super::explicit_outlives_bounds; @@ -75,7 +75,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> { region_bound_pairs: Default::default(), }; - builder.add_outlives_bounds(None, explicit_outlives_bounds(param_env)); + builder.add_outlives_bounds(explicit_outlives_bounds(param_env)); builder } @@ -89,11 +89,10 @@ impl<'tcx> OutlivesEnvironment<'tcx> { /// Create a new `OutlivesEnvironment` with extra outlives bounds. pub fn with_bounds( param_env: ty::ParamEnv<'tcx>, - infcx: Option<&InferCtxt<'tcx>>, extra_bounds: impl IntoIterator>, ) -> Self { let mut builder = Self::builder(param_env); - builder.add_outlives_bounds(infcx, extra_bounds); + builder.add_outlives_bounds(extra_bounds); builder.build() } @@ -120,12 +119,7 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { } /// Processes outlives bounds that are known to hold, whether from implied or other sources. - /// - /// The `infcx` parameter is optional; if the implied bounds may - /// contain inference variables, it must be supplied, in which - /// case we will register "givens" on the inference context. (See - /// `RegionConstraintData`.) - fn add_outlives_bounds(&mut self, infcx: Option<&InferCtxt<'tcx>>, outlives_bounds: I) + fn add_outlives_bounds(&mut self, outlives_bounds: I) where I: IntoIterator>, { @@ -143,24 +137,18 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { .insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a)); } OutlivesBound::RegionSubRegion(r_a, r_b) => { - if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) { - infcx - .expect("no infcx provided but region vars found") - .add_given(r_a, vid_b); - } else { - // In principle, we could record (and take - // advantage of) every relationship here, but - // we are also free not to -- it simply means - // strictly less that we can successfully type - // check. Right now we only look for things - // relationships between free regions. (It may - // also be that we should revise our inference - // system to be more general and to make use - // of *every* relationship that arises here, - // but presently we do not.) - if r_a.is_free_or_static() && r_b.is_free() { - self.region_relation.add(r_a, r_b) - } + // In principle, we could record (and take + // advantage of) every relationship here, but + // we are also free not to -- it simply means + // strictly less that we can successfully type + // check. Right now we only look for things + // relationships between free regions. (It may + // also be that we should revise our inference + // system to be more general and to make use + // of *every* relationship that arises here, + // but presently we do not.) + if r_a.is_free_or_static() && r_b.is_free() { + self.region_relation.add(r_a, r_b) } } } diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index e413b2bb570d6..89ada23c6673a 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -424,9 +424,6 @@ impl<'tcx> MiniGraph<'tcx> { &AddConstraint(Constraint::RegSubReg(a, b)) => { each_edge(a, b); } - &AddGiven(a, b) => { - each_edge(a, tcx.mk_re_var(b)); - } &AddVerify(i) => span_bug!( verifys[i].origin.span(), "we never add verifications while doing higher-ranked things", diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 0b86d9c1fb827..7b272dfd2a454 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -7,7 +7,7 @@ use super::{ InferCtxtUndoLogs, MiscVariable, RegionVariableOrigin, Rollback, Snapshot, SubregionOrigin, }; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::UndoLogs; @@ -104,26 +104,6 @@ pub struct RegionConstraintData<'tcx> { /// An example is a `A <= B` where neither `A` nor `B` are /// inference variables. pub verifys: Vec>, - - /// A "given" is a relationship that is known to hold. In - /// particular, we often know from closure fn signatures that a - /// particular free region must be a subregion of a region - /// variable: - /// - /// foo.iter().filter(<'a> |x: &'a &'b T| ...) - /// - /// In situations like this, `'b` is in fact a region variable - /// introduced by the call to `iter()`, and `'a` is a bound region - /// on the closure (as indicated by the `<'a>` prefix). If we are - /// naive, we wind up inferring that `'b` must be `'static`, - /// because we require that it be greater than `'a` and we do not - /// know what `'a` is precisely. - /// - /// This hashmap is used to avoid that naive scenario. Basically - /// we record the fact that `'a <= 'b` is implied by the fn - /// signature, and then ignore the constraint when solving - /// equations. This is a bit of a hack but seems to work. - pub givens: FxIndexSet<(Region<'tcx>, ty::RegionVid)>, } /// Represents a constraint that influences the inference process. @@ -297,9 +277,6 @@ pub(crate) enum UndoLog<'tcx> { /// We added the given `verify`. AddVerify(usize), - /// We added the given `given`. - AddGiven(Region<'tcx>, ty::RegionVid), - /// We added a GLB/LUB "combination variable". AddCombination(CombineMapType, TwoRegions<'tcx>), } @@ -348,9 +325,6 @@ impl<'tcx> RegionConstraintStorage<'tcx> { self.data.verifys.pop(); assert_eq!(self.data.verifys.len(), index); } - AddGiven(sub, sup) => { - self.data.givens.remove(&(sub, sup)); - } AddCombination(Glb, ref regions) => { self.glbs.remove(regions); } @@ -492,15 +466,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.undo_log.push(AddVerify(index)); } - pub(super) fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) { - // cannot add givens once regions are resolved - if self.data.givens.insert((sub, sup)) { - debug!("add_given({:?} <= {:?})", sub, sup); - - self.undo_log.push(AddGiven(sub, sup)); - } - } - pub(super) fn make_eqregion( &mut self, origin: SubregionOrigin<'tcx>, @@ -804,11 +769,8 @@ impl<'tcx> RegionConstraintData<'tcx> { /// Returns `true` if this region constraint data contains no constraints, and `false` /// otherwise. pub fn is_empty(&self) -> bool { - let RegionConstraintData { constraints, member_constraints, verifys, givens } = self; - constraints.is_empty() - && member_constraints.is_empty() - && verifys.is_empty() - && givens.is_empty() + let RegionConstraintData { constraints, member_constraints, verifys } = self; + constraints.is_empty() && member_constraints.is_empty() && verifys.is_empty() } } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 6b688c322c786..19018764ba25a 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -388,7 +388,6 @@ fn resolve_negative_obligation<'tcx>( let wf_tys = ocx.assumed_wf_types(param_env, DUMMY_SP, body_def_id); let outlives_env = OutlivesEnvironment::with_bounds( param_env, - Some(&infcx), infcx.implied_bounds_tys(param_env, body_def_id, wf_tys), ); diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index b94346b09560a..90d8050412437 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -106,7 +106,6 @@ pub fn type_allowed_to_implement_copy<'tcx>( // Check regions assuming the self type of the impl is WF let outlives_env = OutlivesEnvironment::with_bounds( param_env, - Some(&infcx), infcx.implied_bounds_tys( param_env, parent_cause.body_id, From 4e441565e21a19b8d0be749e997c8b414ba185f4 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 1 Feb 2023 13:52:44 +0300 Subject: [PATCH 078/124] resolve regions before implied bounds --- .../src/traits/outlives_bounds.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 6cb64ad574f5b..e2c198fabde6d 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -3,7 +3,8 @@ use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput}; use crate::traits::query::NoSolution; use crate::traits::ObligationCause; use rustc_data_structures::fx::FxIndexSet; -use rustc_middle::ty::{self, ParamEnv, Ty}; +use rustc_infer::infer::resolve::OpportunisticRegionResolver; +use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt}; use rustc_span::def_id::LocalDefId; pub use rustc_middle::traits::query::OutlivesBound; @@ -52,6 +53,10 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { body_id: LocalDefId, ty: Ty<'tcx>, ) -> Vec> { + let ty = self.resolve_vars_if_possible(ty); + let ty = OpportunisticRegionResolver::new(self).fold_ty(ty); + assert!(!ty.needs_infer()); + let span = self.tcx.def_span(body_id); let result = param_env .and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty }) @@ -105,10 +110,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { tys: FxIndexSet>, ) -> Bounds<'a, 'tcx> { tys.into_iter() - .map(move |ty| { - let ty = self.resolve_vars_if_possible(ty); - self.implied_outlives_bounds(param_env, body_id, ty) - }) + .map(move |ty| self.implied_outlives_bounds(param_env, body_id, ty)) .flatten() } } From 183bd97d076fa2d7bd1c4abcad6065abc17af119 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 1 Feb 2023 14:57:17 +0300 Subject: [PATCH 079/124] add test --- tests/ui/implied-bounds/normalization.rs | 58 ++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 tests/ui/implied-bounds/normalization.rs diff --git a/tests/ui/implied-bounds/normalization.rs b/tests/ui/implied-bounds/normalization.rs new file mode 100644 index 0000000000000..f776fc98a9ede --- /dev/null +++ b/tests/ui/implied-bounds/normalization.rs @@ -0,0 +1,58 @@ +// Test that we get implied bounds from complex projections after normalization. + +// check-pass + +// implementations wil ensure that +// WF(>::Ty) implies T: 'a +trait Combine<'a> { + type Ty; +} + +impl<'a, T: 'a> Combine<'a> for Box { + type Ty = &'a T; +} + +// ======= Wrappers ====== + +// normalizes to a projection +struct WrapA(T); +impl<'a, T> Combine<'a> for WrapA +where + T: Combine<'a>, +{ + type Ty = T::Ty; +} + +// as Combine<'a>>::Ty normalizes to a type variable ?X +// with constraint `>::Ty == ?X` +struct WrapB(T); +impl<'a, X, T> Combine<'a> for WrapB +where + T: Combine<'a, Ty = X>, +{ + type Ty = X; +} + +// as Combine<'a>>::Ty normalizes to `&'a &'?x ()` +// with constraint `>::Ty == &'a &'?x ()` +struct WrapC(T); +impl<'a, 'x: 'a, T> Combine<'a> for WrapC +where + T: Combine<'a, Ty = &'a &'x ()>, +{ + type Ty = &'a &'x (); +} + +//==== Test implied bounds ====== + +fn test_wrap<'a, 'b, 'c1, 'c2, A, B>( + _: > as Combine<'a>>::Ty, // normalized: &'a A + _: > as Combine<'b>>::Ty, // normalized: &'b B + _: > as Combine<'c2>>::Ty, // normalized: &'c2 &'c1 () +) { + None::<&'a A>; + None::<&'b B>; + None::<&'c2 &'c1 ()>; +} + +fn main() {} From 211fa45d18e10f9702a1d9ef529c0f1a867f0712 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Thu, 9 Mar 2023 11:30:49 +0300 Subject: [PATCH 080/124] exhaustive match on implied bounds regions --- .../rustc_infer/src/infer/outlives/env.rs | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index 95f8f05ab6098..a480ee5429eec 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -136,21 +136,14 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { self.region_bound_pairs .insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a)); } - OutlivesBound::RegionSubRegion(r_a, r_b) => { - // In principle, we could record (and take - // advantage of) every relationship here, but - // we are also free not to -- it simply means - // strictly less that we can successfully type - // check. Right now we only look for things - // relationships between free regions. (It may - // also be that we should revise our inference - // system to be more general and to make use - // of *every* relationship that arises here, - // but presently we do not.) - if r_a.is_free_or_static() && r_b.is_free() { - self.region_relation.add(r_a, r_b) - } - } + OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) { + ( + ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_), + ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_), + ) => self.region_relation.add(r_a, r_b), + (ty::ReError(_), _) | (_, ty::ReError(_)) => {} + _ => bug!("add_outlives_bounds: unexpected regions"), + }, } } } From 0738ffe4198b190a81a13e1f1da41651ec6cbfb0 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 17 Nov 2022 10:33:10 +0100 Subject: [PATCH 081/124] replace legacy copyright annotations in submodules --- example/alloc_system.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/example/alloc_system.rs b/example/alloc_system.rs index 50261c1939739..e64daf96b01c9 100644 --- a/example/alloc_system.rs +++ b/example/alloc_system.rs @@ -1,12 +1,6 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. +// SPDX-License-Identifier: MIT OR Apache-2.0 +// SPDX-FileCopyrightText: The Rust Project Developers (see https://thanks.rust-lang.org) + #![no_std] pub struct System; From 82e675061c28fe99db0c94058164a3485357250a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 6 Sep 2022 18:41:01 +0200 Subject: [PATCH 082/124] Introduce a no-op PlaceMention statement for `let _ =`. --- src/base.rs | 1 + src/constant.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/base.rs b/src/base.rs index cb0e272cedaba..230256ba5aa84 100644 --- a/src/base.rs +++ b/src/base.rs @@ -819,6 +819,7 @@ fn codegen_stmt<'tcx>( | StatementKind::Nop | StatementKind::FakeRead(..) | StatementKind::Retag { .. } + | StatementKind::PlaceMention(..) | StatementKind::AscribeUserType(..) => {} StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"), diff --git a/src/constant.rs b/src/constant.rs index 1930db72ead44..efdf9f6d5bc02 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -529,6 +529,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( | StatementKind::StorageDead(_) | StatementKind::Retag(_, _) | StatementKind::AscribeUserType(_, _) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(_) | StatementKind::ConstEvalCounter | StatementKind::Nop => {} From f2c81bb1c0316e59d73280712e839f8decddaa1a Mon Sep 17 00:00:00 2001 From: Collin Baker Date: Mon, 13 Feb 2023 18:48:06 -0500 Subject: [PATCH 083/124] Don't export of __rust_* alloc symbols if not codegened --- src/allocator.rs | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 1c73957ca571c..2c246ceb37d54 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -4,6 +4,7 @@ use crate::prelude::*; use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; +use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; use rustc_span::symbol::sym; @@ -13,24 +14,15 @@ pub(crate) fn codegen( module: &mut impl Module, unwind_context: &mut UnwindContext, ) -> bool { - let any_dynamic_crate = tcx.dependency_formats(()).iter().any(|(_, list)| { - use rustc_middle::middle::dependency_format::Linkage; - list.iter().any(|&linkage| linkage == Linkage::Dynamic) - }); - if any_dynamic_crate { - false - } else if let Some(kind) = tcx.allocator_kind(()) { - codegen_inner( - module, - unwind_context, - kind, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); - true - } else { - false - } + let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; + codegen_inner( + module, + unwind_context, + kind, + tcx.alloc_error_handler_kind(()).unwrap(), + tcx.sess.opts.unstable_opts.oom, + ); + true } fn codegen_inner( From e781db8d443243e70975e31dea828c033431632a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 10 Mar 2023 14:12:47 +0100 Subject: [PATCH 084/124] Rustup to rustc 1.70.0-nightly (39f2657d1 2023-03-09) --- build_sysroot/Cargo.lock | 4 ++-- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index 5f25d7e9ad473..1eadc8a4db6e1 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" dependencies = [ "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index 98dd946c92ea5..1c2e2f90676b9 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-03-04" +channel = "nightly-2023-03-10" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 0b9e8c65d5b590ae215ffdcd63d3c9c6031e331c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 10 Mar 2023 13:44:34 +0000 Subject: [PATCH 085/124] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 7952a2c86aed8..20dcb4cf34d2f 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -81,6 +81,7 @@ rm tests/ui/layout/valid_range_oob.rs # different ICE message rm tests/ui/consts/issue-miri-1910.rs # different error message rm tests/ui/consts/offset_ub.rs # same +rm tests/ui/consts/const-eval/ub-slice-get-unchecked.rs # same rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # same rm tests/ui/lint/lint-const-item-mutation.rs # same rm tests/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs # same From b2c717fa338dd3e917008484c4bf55886041f743 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 11 Mar 2023 15:32:54 -0800 Subject: [PATCH 086/124] `MaybeUninit::assume_init_read` should have `noundef` load metadata I was looking into `array::IntoIter` optimization, and noticed that it wasn't annotating the loads with `noundef` for simple things like `array::IntoIter`. Turned out to be a more general problem as `MaybeUninit::assume_init_read` isn't marking the load as initialized (), which is unfortunate since that's basically its reason to exist. This PR lowers `ptr::read(p)` to `copy *p` in MIR, which fortuitiously also improves the IR we give to LLVM for things like `mem::replace`. --- .../rustc_hir_analysis/src/check/intrinsic.rs | 2 + compiler/rustc_lint_defs/src/builtin.rs | 7 +-- .../src/lower_intrinsics.rs | 24 +++++++++ compiler/rustc_span/src/symbol.rs | 1 + library/core/src/intrinsics.rs | 14 +++++ library/core/src/ptr/mod.rs | 20 +++++--- tests/codegen/mem-replace-direct-memcpy.rs | 41 +++++++++++++-- tests/codegen/read-noundef-metadata.rs | 51 +++++++++++++++++++ ...ad_via_copy_primitive.LowerIntrinsics.diff | 27 ++++++++++ ..._via_copy_uninhabited.LowerIntrinsics.diff | 22 ++++++++ tests/mir-opt/lower_intrinsics.rs | 12 +++++ tests/ui/const-ptr/out_of_bounds_read.stderr | 6 +-- tests/ui/consts/const-eval/ub-ref-ptr.stderr | 24 ++------- tests/ui/consts/issue-miri-1910.stderr | 2 +- 14 files changed, 214 insertions(+), 39 deletions(-) create mode 100644 tests/codegen/read-noundef-metadata.rs create mode 100644 tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff create mode 100644 tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 20b6561f8b256..8c364a4f3b2b8 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -363,6 +363,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { sym::likely => (0, vec![tcx.types.bool], tcx.types.bool), sym::unlikely => (0, vec![tcx.types.bool], tcx.types.bool), + sym::read_via_copy => (1, vec![tcx.mk_imm_ptr(param(0))], param(0)), + sym::discriminant_value => { let assoc_items = tcx.associated_item_def_ids( tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 46ec1a2dca1f7..91966e75b5fa2 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1026,12 +1026,13 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail - /// #![feature(const_ptr_read)] + /// #![feature(const_mut_refs)] /// const FOO: () = unsafe { /// let x = &[0_u8; 4]; /// let y = x.as_ptr().cast::(); - /// y.read(); // the address of a `u8` array is unknown and thus we don't know if - /// // it is aligned enough for reading a `u32`. + /// let mut z = 123; + /// y.copy_to_nonoverlapping(&mut z, 1); // the address of a `u8` array is unknown + /// // and thus we don't know if it is aligned enough for copying a `u32`. /// }; /// ``` /// diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index f596cc1808fa2..151fff27d14ad 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -149,6 +149,30 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Goto { target }; } } + sym::read_via_copy => { + let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else { + span_bug!(terminator.source_info.span, "Wrong number of arguments"); + }; + let derefed_place = + if let Some(place) = arg.place() && let Some(local) = place.as_local() { + tcx.mk_place_deref(local.into()) + } else { + span_bug!(terminator.source_info.span, "Only passing a local is supported"); + }; + block.statements.push(Statement { + source_info: terminator.source_info, + kind: StatementKind::Assign(Box::new(( + *destination, + Rvalue::Use(Operand::Copy(derefed_place)), + ))), + }); + if let Some(target) = *target { + terminator.kind = TerminatorKind::Goto { target }; + } else { + // Reading something uninhabited means this is unreachable. + terminator.kind = TerminatorKind::Unreachable; + } + } sym::discriminant_value => { if let (Some(target), Some(arg)) = (*target, args[0].place()) { let arg = tcx.mk_place_deref(arg); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4e626fd9f30c0..45f79c9d80592 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1153,6 +1153,7 @@ symbols! { read_enum_variant_arg, read_struct, read_struct_field, + read_via_copy, readonly, realloc, reason, diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index c6321587adc62..d77c2a00eb780 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2020,6 +2020,20 @@ extern "rust-intrinsic" { #[rustc_safe_intrinsic] pub fn saturating_sub(a: T, b: T) -> T; + /// This is a *typed* read, `copy *p` in MIR. + /// + /// The stabilized form of this intrinsic is [`crate::ptr::read`], so + /// that can be implemented without needing to do an *untyped* copy + /// via [`copy_nonoverlapping`], and thus can get proper metadata. + /// + /// This intrinsic can *only* be called with a copy or move of a local. + /// (It allows neither constants nor projections.) + /// + /// To avoid introducing any `noalias` requirements, it just takes a pointer. + #[cfg(not(bootstrap))] + #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] + pub fn read_via_copy(p: *const T) -> T; + /// Returns the value of the discriminant for the variant in 'v'; /// if `T` has no discriminant, returns `0`. /// diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index f41be46abc96f..04b67a56db59b 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1137,25 +1137,33 @@ pub const unsafe fn replace(dst: *mut T, mut src: T) -> T { pub const unsafe fn read(src: *const T) -> T { // We are calling the intrinsics directly to avoid function calls in the generated code // as `intrinsics::copy_nonoverlapping` is a wrapper function. + #[cfg(bootstrap)] extern "rust-intrinsic" { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); } - let mut tmp = MaybeUninit::::uninit(); // SAFETY: the caller must guarantee that `src` is valid for reads. // `src` cannot overlap `tmp` because `tmp` was just allocated on // the stack as a separate allocated object. - // - // Also, since we just wrote a valid value into `tmp`, it is guaranteed - // to be properly initialized. unsafe { assert_unsafe_precondition!( "ptr::read requires that the pointer argument is aligned and non-null", [T](src: *const T) => is_aligned_and_not_null(src) ); - copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - tmp.assume_init() + + #[cfg(bootstrap)] + { + let mut tmp = MaybeUninit::::uninit(); + copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); + tmp.assume_init() + } + #[cfg(not(bootstrap))] + { + // This uses a dedicated intrinsic, not `copy_nonoverlapping`, + // so that it gets a *typed* copy, not an *untyped* one. + crate::intrinsics::read_via_copy(src) + } } } diff --git a/tests/codegen/mem-replace-direct-memcpy.rs b/tests/codegen/mem-replace-direct-memcpy.rs index e8bbf0e1bbd61..3b01a621b5680 100644 --- a/tests/codegen/mem-replace-direct-memcpy.rs +++ b/tests/codegen/mem-replace-direct-memcpy.rs @@ -12,13 +12,44 @@ pub fn replace_byte(dst: &mut u8, src: u8) -> u8 { std::mem::replace(dst, src) } +#[repr(C, align(8))] +pub struct Big([u64; 7]); +pub fn replace_big(dst: &mut Big, src: Big) -> Big { + // Before the `read_via_copy` intrinsic, this emitted six `memcpy`s. + std::mem::replace(dst, src) +} + // NOTE(eddyb) the `CHECK-NOT`s ensure that the only calls of `@llvm.memcpy` in -// the entire output, are the two direct calls we want, from `ptr::replace`. +// the entire output, are the direct calls we want, from `ptr::replace`. // CHECK-NOT: call void @llvm.memcpy -// CHECK: ; core::mem::replace -// CHECK-NOT: call void @llvm.memcpy -// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{.*}} 1, i1 false) + +// For a large type, we expect exactly three `memcpy`s +// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big) + // CHECK-NOT: alloca + // CHECK: alloca %Big + // CHECK-NOT: alloca + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) + // CHECK-NOT: call void @llvm.memcpy + // CHECK-NOT: call void @llvm.memcpy -// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{.*}} 1, i1 false) + +// For a small type, we expect one each of `load`/`store`/`memcpy` instead +// CHECK-LABEL: define internal noundef i8 @{{.+}}mem{{.+}}replace + // CHECK-NOT: alloca + // CHECK: alloca i8 + // CHECK-NOT: alloca + // CHECK-NOT: call void @llvm.memcpy + // CHECK: load i8 + // CHECK-NOT: call void @llvm.memcpy + // CHECK: store i8 + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{.*}} 1, i1 false) + // CHECK-NOT: call void @llvm.memcpy + // CHECK-NOT: call void @llvm.memcpy diff --git a/tests/codegen/read-noundef-metadata.rs b/tests/codegen/read-noundef-metadata.rs new file mode 100644 index 0000000000000..03386921c43e3 --- /dev/null +++ b/tests/codegen/read-noundef-metadata.rs @@ -0,0 +1,51 @@ +// compile-flags: -O -Z merge-functions=disabled +// no-system-llvm +// ignore-debug (the extra assertions get in the way) + +#![crate_type = "lib"] + +// Ensure that various forms of reading pointers correctly annotate the `load`s +// with `!noundef` metadata to enable extra optimization. The functions return +// `MaybeUninit` to keep it from being inferred from the function type. + +use std::mem::MaybeUninit; + +// CHECK-LABEL: define i8 @copy_byte( +#[no_mangle] +pub unsafe fn copy_byte(p: *const u8) -> MaybeUninit { + // CHECK-NOT: load + // CHECK: load i8, ptr %p, align 1 + // CHECK-SAME: !noundef ! + // CHECK-NOT: load + MaybeUninit::new(*p) +} + +// CHECK-LABEL: define i8 @read_byte( +#[no_mangle] +pub unsafe fn read_byte(p: *const u8) -> MaybeUninit { + // CHECK-NOT: load + // CHECK: load i8, ptr %p, align 1 + // CHECK-SAME: !noundef ! + // CHECK-NOT: load + MaybeUninit::new(p.read()) +} + +// CHECK-LABEL: define i8 @read_byte_maybe_uninit( +#[no_mangle] +pub unsafe fn read_byte_maybe_uninit(p: *const MaybeUninit) -> MaybeUninit { + // CHECK-NOT: load + // CHECK: load i8, ptr %p, align 1 + // CHECK-NOT: noundef + // CHECK-NOT: load + p.read() +} + +// CHECK-LABEL: define i8 @read_byte_assume_init( +#[no_mangle] +pub unsafe fn read_byte_assume_init(p: &MaybeUninit) -> MaybeUninit { + // CHECK-NOT: load + // CHECK: load i8, ptr %p, align 1 + // CHECK-SAME: !noundef ! + // CHECK-NOT: load + MaybeUninit::new(p.assume_init_read()) +} diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff new file mode 100644 index 0000000000000..27fceeedf6e2c --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff @@ -0,0 +1,27 @@ +- // MIR for `read_via_copy_primitive` before LowerIntrinsics ++ // MIR for `read_via_copy_primitive` after LowerIntrinsics + + fn read_via_copy_primitive(_1: &i32) -> i32 { + debug r => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:32: +0:33 + let mut _0: i32; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:44: +0:47 + let mut _2: *const i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + _2 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 +- _0 = read_via_copy::(move _2) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:85:14: 85:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32) -> i32 {read_via_copy::}, val: Value() } ++ _0 = (*_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 ++ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 + } + + bb1: { + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 + return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff new file mode 100644 index 0000000000000..faf3f9c31b82f --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff @@ -0,0 +1,22 @@ +- // MIR for `read_via_copy_uninhabited` before LowerIntrinsics ++ // MIR for `read_via_copy_uninhabited` after LowerIntrinsics + + fn read_via_copy_uninhabited(_1: &Never) -> Never { + debug r => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:34: +0:35 + let mut _0: Never; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:48: +0:53 + let mut _2: *const Never; // in scope 0 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + scope 1 { + } + + bb0: { + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 + _2 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 +- _0 = read_via_copy::(move _2); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:90:14: 90:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Never) -> Never {read_via_copy::}, val: Value() } ++ _0 = (*_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 ++ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 + } + } + diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs index 7147be43ca5e3..a0a1df4e5ca86 100644 --- a/tests/mir-opt/lower_intrinsics.rs +++ b/tests/mir-opt/lower_intrinsics.rs @@ -79,3 +79,15 @@ pub fn with_overflow(a: i32, b: i32) { let _y = core::intrinsics::sub_with_overflow(a, b); let _z = core::intrinsics::mul_with_overflow(a, b); } + +// EMIT_MIR lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff +pub fn read_via_copy_primitive(r: &i32) -> i32 { + unsafe { core::intrinsics::read_via_copy(r) } +} + +// EMIT_MIR lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff +pub fn read_via_copy_uninhabited(r: &Never) -> Never { + unsafe { core::intrinsics::read_via_copy(r) } +} + +pub enum Never {} diff --git a/tests/ui/const-ptr/out_of_bounds_read.stderr b/tests/ui/const-ptr/out_of_bounds_read.stderr index 3e7b09a5982d9..89536f53f08b0 100644 --- a/tests/ui/const-ptr/out_of_bounds_read.stderr +++ b/tests/ui/const-ptr/out_of_bounds_read.stderr @@ -1,7 +1,7 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + = note: dereferencing pointer failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | note: inside `std::ptr::read::` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL @@ -14,7 +14,7 @@ LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) }; error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + = note: dereferencing pointer failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | note: inside `std::ptr::read::` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL @@ -29,7 +29,7 @@ LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() }; error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds + = note: dereferencing pointer failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds | note: inside `std::ptr::read::` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index 6bd367b646902..080568b51ef71 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr @@ -148,11 +148,11 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; HEX_DUMP } -error: accessing memory with alignment 1, but alignment 4 is required +error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #68585 + = note: accessing memory with alignment 1, but alignment 4 is required + | note: inside `std::ptr::read::` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `ptr::const_ptr::::read` @@ -162,25 +162,7 @@ note: inside `UNALIGNED_READ` | LL | ptr.read(); | ^^^^^^^^^^ - = note: `#[deny(invalid_alignment)]` on by default error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0080`. -Future incompatibility report: Future breakage diagnostic: -error: accessing memory with alignment 1, but alignment 4 is required - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #68585 -note: inside `std::ptr::read::` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `ptr::const_ptr::::read` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `UNALIGNED_READ` - --> $DIR/ub-ref-ptr.rs:67:5 - | -LL | ptr.read(); - | ^^^^^^^^^^ - = note: `#[deny(invalid_alignment)]` on by default - diff --git a/tests/ui/consts/issue-miri-1910.stderr b/tests/ui/consts/issue-miri-1910.stderr index 61865b1dad764..a10eea9de114f 100644 --- a/tests/ui/consts/issue-miri-1910.stderr +++ b/tests/ui/consts/issue-miri-1910.stderr @@ -1,7 +1,7 @@ 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 + = note: unable to turn pointer into raw bytes | = 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 From 2c122a8926274dc6bdedcbef7974539f05af627a Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Feb 2023 13:07:44 +0000 Subject: [PATCH 087/124] Remove uses of `box_syntax` in rustc and tools --- example/alloc_example.rs | 4 ++-- example/mini_core_hello_world.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/example/alloc_example.rs b/example/alloc_example.rs index bc1594d82ecf9..4ede2fe4efe82 100644 --- a/example/alloc_example.rs +++ b/example/alloc_example.rs @@ -1,4 +1,4 @@ -#![feature(start, core_intrinsics, alloc_error_handler, box_syntax)] +#![feature(start, core_intrinsics, alloc_error_handler)] #![no_std] extern crate alloc; @@ -29,7 +29,7 @@ fn alloc_error_handler(_: alloc::alloc::Layout) -> ! { #[start] fn main(_argc: isize, _argv: *const *const u8) -> isize { - let world: Box<&str> = box "Hello World!\0"; + let world: Box<&str> = Box::new("Hello World!\0"); unsafe { puts(*world as *const str as *const u8); } diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index c00f8a2e0cdad..04e7795bbfa16 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -1,4 +1,4 @@ -#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, box_syntax)] +#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local)] #![no_core] #![allow(dead_code, non_camel_case_types)] @@ -178,7 +178,7 @@ fn main() { let ptr: *const i8 = hello as *const [u8] as *const i8; puts(ptr); - let world: Box<&str> = box "World!\0"; + let world: Box<&str> = Box::new("World!\0"); puts(*world as *const str as *const i8); world as Box; @@ -238,10 +238,10 @@ fn main() { } } - let _ = box NoisyDrop { + let _ = Box::new(NoisyDrop { text: "Boxed outer got dropped!\0", inner: NoisyDropInner, - } as Box; + }) as Box; const FUNC_REF: Option = Some(main); match FUNC_REF { From 8a5574bf62825d5302cd89428d9bae76e93b3311 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 7 Mar 2023 18:27:38 -0300 Subject: [PATCH 088/124] Remove tests/ui/impl-trait/in-trait/new-lowering-strategy in favor of using revisions on existing tests --- .../new-lowering-strategy/simple-impl-trait.rs | 17 ----------------- .../new-lowering-strategy/simple-trait.rs | 11 ----------- 2 files changed, 28 deletions(-) delete mode 100644 tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-impl-trait.rs delete mode 100644 tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs diff --git a/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-impl-trait.rs b/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-impl-trait.rs deleted file mode 100644 index ae09d20f6f5b7..0000000000000 --- a/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-impl-trait.rs +++ /dev/null @@ -1,17 +0,0 @@ -// check-pass -// compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty - -#![feature(return_position_impl_trait_in_trait)] -#![allow(incomplete_features)] - -trait Foo { - fn foo() -> impl Sized; -} - -impl Foo for String { - fn foo() -> i32 { - 22 - } -} - -fn main() {} diff --git a/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs b/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs deleted file mode 100644 index dfce973d770b9..0000000000000 --- a/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs +++ /dev/null @@ -1,11 +0,0 @@ -// check-pass -// compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty - -#![feature(return_position_impl_trait_in_trait)] -#![allow(incomplete_features)] - -trait Foo { - fn foo() -> impl Sized; -} - -fn main() {} From 07e018dfef2f3f213a649181009623200b9f488c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 7 Mar 2023 18:26:02 -0300 Subject: [PATCH 089/124] Run existing async in traits tests using -Zlower-impl-trait-in-trait-to-assoc-ty --- .../in-trait/async-associated-types.rs | 2 ++ .../in-trait/async-associated-types2.rs | 2 ++ ...e-desugared-boxed-in-trait.current.stderr} | 4 +-- ...ample-desugared-boxed-in-trait.next.stderr | 17 ++++++++++++ .../async-example-desugared-boxed-in-trait.rs | 2 ++ ...nc-example-desugared-boxed.current.stderr} | 2 +- .../async-example-desugared-boxed.next.stderr | 11 ++++++++ .../in-trait/async-example-desugared-boxed.rs | 2 ++ .../in-trait/async-example-desugared-extra.rs | 2 ++ .../async-example-desugared-in-trait.rs | 2 ++ ...c-example-desugared-manual.current.stderr} | 2 +- ...async-example-desugared-manual.next.stderr | 11 ++++++++ .../async-example-desugared-manual.rs | 2 ++ .../in-trait/async-example-desugared.rs | 2 ++ ...=> async-recursive-generic.current.stderr} | 2 +- .../async-recursive-generic.next.stderr | 12 +++++++++ .../in-trait/async-recursive-generic.rs | 2 ++ ....stderr => async-recursive.current.stderr} | 2 +- .../in-trait/async-recursive.next.stderr | 12 +++++++++ .../async-await/in-trait/async-recursive.rs | 2 ++ ...s.stderr => bad-signatures.current.stderr} | 6 ++--- .../in-trait/bad-signatures.next.stderr | 26 +++++++++++++++++++ .../ui/async-await/in-trait/bad-signatures.rs | 2 ++ .../ui/async-await/in-trait/early-bound-1.rs | 2 ++ .../ui/async-await/in-trait/early-bound-2.rs | 2 ++ ...tderr => fn-not-async-err2.current.stderr} | 2 +- .../in-trait/fn-not-async-err2.next.stderr | 12 +++++++++ .../async-await/in-trait/fn-not-async-err2.rs | 2 ++ .../ui/async-await/in-trait/implied-bounds.rs | 2 ++ tests/ui/async-await/in-trait/issue-102138.rs | 2 ++ tests/ui/async-await/in-trait/issue-102219.rs | 2 ++ 31 files changed, 145 insertions(+), 10 deletions(-) rename tests/ui/async-await/in-trait/{async-example-desugared-boxed-in-trait.stderr => async-example-desugared-boxed-in-trait.current.stderr} (84%) create mode 100644 tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr rename tests/ui/async-await/in-trait/{async-example-desugared-boxed.stderr => async-example-desugared-boxed.current.stderr} (88%) create mode 100644 tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr rename tests/ui/async-await/in-trait/{async-example-desugared-manual.stderr => async-example-desugared-manual.current.stderr} (86%) create mode 100644 tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr rename tests/ui/async-await/in-trait/{async-recursive-generic.stderr => async-recursive-generic.current.stderr} (91%) create mode 100644 tests/ui/async-await/in-trait/async-recursive-generic.next.stderr rename tests/ui/async-await/in-trait/{async-recursive.stderr => async-recursive.current.stderr} (93%) create mode 100644 tests/ui/async-await/in-trait/async-recursive.next.stderr rename tests/ui/async-await/in-trait/{bad-signatures.stderr => bad-signatures.current.stderr} (89%) create mode 100644 tests/ui/async-await/in-trait/bad-signatures.next.stderr rename tests/ui/async-await/in-trait/{fn-not-async-err2.stderr => fn-not-async-err2.current.stderr} (93%) create mode 100644 tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr diff --git a/tests/ui/async-await/in-trait/async-associated-types.rs b/tests/ui/async-await/in-trait/async-associated-types.rs index 974f5aaff83c3..89ca4039bce91 100644 --- a/tests/ui/async-await/in-trait/async-associated-types.rs +++ b/tests/ui/async-await/in-trait/async-associated-types.rs @@ -1,5 +1,7 @@ // check-pass // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![feature(impl_trait_projections)] diff --git a/tests/ui/async-await/in-trait/async-associated-types2.rs b/tests/ui/async-await/in-trait/async-associated-types2.rs index e546a0579c66f..cdecb02bfad1e 100644 --- a/tests/ui/async-await/in-trait/async-associated-types2.rs +++ b/tests/ui/async-await/in-trait/async-associated-types2.rs @@ -1,5 +1,7 @@ // check-pass // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![feature(type_alias_impl_trait)] diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr similarity index 84% rename from tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr rename to tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr index 168ef8e9ee4e7..b5ace9ada4f80 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr @@ -1,11 +1,11 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:15:28 + --> $DIR/async-example-desugared-boxed-in-trait.rs:17:28 | LL | async fn foo(&self) -> i32 { | ^^^ expected `Pin>>`, found future | note: type in trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:11:22 + --> $DIR/async-example-desugared-boxed-in-trait.rs:13:22 | LL | fn foo(&self) -> Pin + '_>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr new file mode 100644 index 0000000000000..b5ace9ada4f80 --- /dev/null +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr @@ -0,0 +1,17 @@ +error[E0053]: method `foo` has an incompatible type for trait + --> $DIR/async-example-desugared-boxed-in-trait.rs:17:28 + | +LL | async fn foo(&self) -> i32 { + | ^^^ expected `Pin>>`, found future + | +note: type in trait + --> $DIR/async-example-desugared-boxed-in-trait.rs:13:22 + | +LL | fn foo(&self) -> Pin + '_>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected signature `fn(&i32) -> Pin>>` + found signature `fn(&i32) -> impl Future` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs index 38ba297189c69..7b53379b24b78 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs @@ -1,4 +1,6 @@ // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![feature(return_position_impl_trait_in_trait)] diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr similarity index 88% rename from tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr rename to tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr index 60fa534a64f02..6c0b5859186b5 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr @@ -1,5 +1,5 @@ error: method `foo` should be async because the method from the trait is async - --> $DIR/async-example-desugared-boxed.rs:15:5 + --> $DIR/async-example-desugared-boxed.rs:17:5 | LL | async fn foo(&self) -> i32; | --------------------------- required because the trait method is async diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr new file mode 100644 index 0000000000000..6c0b5859186b5 --- /dev/null +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr @@ -0,0 +1,11 @@ +error: method `foo` should be async because the method from the trait is async + --> $DIR/async-example-desugared-boxed.rs:17:5 + | +LL | async fn foo(&self) -> i32; + | --------------------------- required because the trait method is async +... +LL | fn foo(&self) -> Pin + '_>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs index 1b1b3cffd58f3..916488ffafaf4 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs @@ -1,4 +1,6 @@ // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![feature(return_position_impl_trait_in_trait)] diff --git a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs index 81e1e59a36249..edac0b374a325 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs @@ -1,5 +1,7 @@ // check-pass // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![feature(return_position_impl_trait_in_trait)] diff --git a/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs b/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs index feeda719e0306..934f7643dd1c9 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs @@ -1,5 +1,7 @@ // check-pass // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![feature(return_position_impl_trait_in_trait)] diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr similarity index 86% rename from tests/ui/async-await/in-trait/async-example-desugared-manual.stderr rename to tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr index 567a36a86d191..0d2551ab84f95 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr @@ -1,5 +1,5 @@ error: method `foo` should be async because the method from the trait is async - --> $DIR/async-example-desugared-manual.rs:23:5 + --> $DIR/async-example-desugared-manual.rs:25:5 | LL | async fn foo(&self) -> i32; | --------------------------- required because the trait method is async diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr new file mode 100644 index 0000000000000..0d2551ab84f95 --- /dev/null +++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr @@ -0,0 +1,11 @@ +error: method `foo` should be async because the method from the trait is async + --> $DIR/async-example-desugared-manual.rs:25:5 + | +LL | async fn foo(&self) -> i32; + | --------------------------- required because the trait method is async +... +LL | fn foo(&self) -> MyFuture { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs index 71473e7455fd6..4883828d32fef 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs @@ -1,4 +1,6 @@ // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![feature(return_position_impl_trait_in_trait)] diff --git a/tests/ui/async-await/in-trait/async-example-desugared.rs b/tests/ui/async-await/in-trait/async-example-desugared.rs index fb92ec786746f..214171b2e2cba 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared.rs @@ -1,5 +1,7 @@ // check-pass // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![feature(return_position_impl_trait_in_trait)] diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr similarity index 91% rename from tests/ui/async-await/in-trait/async-recursive-generic.stderr rename to tests/ui/async-await/in-trait/async-recursive-generic.current.stderr index cab173bdd5b70..67b491f19d269 100644 --- a/tests/ui/async-await/in-trait/async-recursive-generic.stderr +++ b/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr @@ -1,5 +1,5 @@ error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive-generic.rs:11:48 + --> $DIR/async-recursive-generic.rs:13:48 | LL | async fn foo_recursive(&self, n: usize) -> T { | ^ recursive `async fn` diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr new file mode 100644 index 0000000000000..67b491f19d269 --- /dev/null +++ b/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr @@ -0,0 +1,12 @@ +error[E0733]: recursion in an `async fn` requires boxing + --> $DIR/async-recursive-generic.rs:13:48 + | +LL | async fn foo_recursive(&self, n: usize) -> T { + | ^ recursive `async fn` + | + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` + = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0733`. diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.rs b/tests/ui/async-await/in-trait/async-recursive-generic.rs index 6839abd381c3f..64c6ba15c0cf0 100644 --- a/tests/ui/async-await/in-trait/async-recursive-generic.rs +++ b/tests/ui/async-await/in-trait/async-recursive-generic.rs @@ -1,4 +1,6 @@ // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/in-trait/async-recursive.stderr b/tests/ui/async-await/in-trait/async-recursive.current.stderr similarity index 93% rename from tests/ui/async-await/in-trait/async-recursive.stderr rename to tests/ui/async-await/in-trait/async-recursive.current.stderr index 9feff37b3fe46..85af27e374653 100644 --- a/tests/ui/async-await/in-trait/async-recursive.stderr +++ b/tests/ui/async-await/in-trait/async-recursive.current.stderr @@ -1,5 +1,5 @@ error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive.rs:11:48 + --> $DIR/async-recursive.rs:13:48 | LL | async fn foo_recursive(&self, n: usize) -> i32 { | ^^^ recursive `async fn` diff --git a/tests/ui/async-await/in-trait/async-recursive.next.stderr b/tests/ui/async-await/in-trait/async-recursive.next.stderr new file mode 100644 index 0000000000000..85af27e374653 --- /dev/null +++ b/tests/ui/async-await/in-trait/async-recursive.next.stderr @@ -0,0 +1,12 @@ +error[E0733]: recursion in an `async fn` requires boxing + --> $DIR/async-recursive.rs:13:48 + | +LL | async fn foo_recursive(&self, n: usize) -> i32 { + | ^^^ recursive `async fn` + | + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` + = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0733`. diff --git a/tests/ui/async-await/in-trait/async-recursive.rs b/tests/ui/async-await/in-trait/async-recursive.rs index 61119f8095bcc..d928909e3ae5b 100644 --- a/tests/ui/async-await/in-trait/async-recursive.rs +++ b/tests/ui/async-await/in-trait/async-recursive.rs @@ -1,4 +1,6 @@ // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/in-trait/bad-signatures.stderr b/tests/ui/async-await/in-trait/bad-signatures.current.stderr similarity index 89% rename from tests/ui/async-await/in-trait/bad-signatures.stderr rename to tests/ui/async-await/in-trait/bad-signatures.current.stderr index e0ba7b53ec415..5a05b080c3e57 100644 --- a/tests/ui/async-await/in-trait/bad-signatures.stderr +++ b/tests/ui/async-await/in-trait/bad-signatures.current.stderr @@ -1,11 +1,11 @@ error: expected identifier, found keyword `self` - --> $DIR/bad-signatures.rs:7:23 + --> $DIR/bad-signatures.rs:9:23 | LL | async fn bar(&abc self); | ^^^^ expected identifier, found keyword error: expected one of `:`, `@`, or `|`, found keyword `self` - --> $DIR/bad-signatures.rs:7:23 + --> $DIR/bad-signatures.rs:9:23 | LL | async fn bar(&abc self); | -----^^^^ @@ -14,7 +14,7 @@ LL | async fn bar(&abc self); | help: declare the type after the parameter binding: `: ` warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-signatures.rs:3:12 + --> $DIR/bad-signatures.rs:5:12 | LL | #![feature(async_fn_in_trait)] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/bad-signatures.next.stderr b/tests/ui/async-await/in-trait/bad-signatures.next.stderr new file mode 100644 index 0000000000000..5a05b080c3e57 --- /dev/null +++ b/tests/ui/async-await/in-trait/bad-signatures.next.stderr @@ -0,0 +1,26 @@ +error: expected identifier, found keyword `self` + --> $DIR/bad-signatures.rs:9:23 + | +LL | async fn bar(&abc self); + | ^^^^ expected identifier, found keyword + +error: expected one of `:`, `@`, or `|`, found keyword `self` + --> $DIR/bad-signatures.rs:9:23 + | +LL | async fn bar(&abc self); + | -----^^^^ + | | | + | | expected one of `:`, `@`, or `|` + | help: declare the type after the parameter binding: `: ` + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-signatures.rs:5:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 2 previous errors; 1 warning emitted + diff --git a/tests/ui/async-await/in-trait/bad-signatures.rs b/tests/ui/async-await/in-trait/bad-signatures.rs index b86f1d1c13585..e0093be8cb33f 100644 --- a/tests/ui/async-await/in-trait/bad-signatures.rs +++ b/tests/ui/async-await/in-trait/bad-signatures.rs @@ -1,4 +1,6 @@ // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] //~^ WARN the feature `async_fn_in_trait` is incomplete diff --git a/tests/ui/async-await/in-trait/early-bound-1.rs b/tests/ui/async-await/in-trait/early-bound-1.rs index 6b3b142014bd3..30843473defc7 100644 --- a/tests/ui/async-await/in-trait/early-bound-1.rs +++ b/tests/ui/async-await/in-trait/early-bound-1.rs @@ -1,5 +1,7 @@ // check-pass // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/in-trait/early-bound-2.rs b/tests/ui/async-await/in-trait/early-bound-2.rs index 270443229b054..1c5a68c2a5adf 100644 --- a/tests/ui/async-await/in-trait/early-bound-2.rs +++ b/tests/ui/async-await/in-trait/early-bound-2.rs @@ -1,5 +1,7 @@ // check-pass // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr similarity index 93% rename from tests/ui/async-await/in-trait/fn-not-async-err2.stderr rename to tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr index 37d9669c0124b..1a7495149899a 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr @@ -1,5 +1,5 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types - --> $DIR/fn-not-async-err2.rs:13:22 + --> $DIR/fn-not-async-err2.rs:15:22 | LL | fn foo(&self) -> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr new file mode 100644 index 0000000000000..1a7495149899a --- /dev/null +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr @@ -0,0 +1,12 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types + --> $DIR/fn-not-async-err2.rs:15:22 + | +LL | fn foo(&self) -> impl Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.rs b/tests/ui/async-await/in-trait/fn-not-async-err2.rs index 78017429f73d5..5fdb7296aaf97 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.rs +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.rs @@ -1,4 +1,6 @@ // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/in-trait/implied-bounds.rs b/tests/ui/async-await/in-trait/implied-bounds.rs index 52bceb3cc5cd6..45ada1d84c320 100644 --- a/tests/ui/async-await/in-trait/implied-bounds.rs +++ b/tests/ui/async-await/in-trait/implied-bounds.rs @@ -1,5 +1,7 @@ // check-pass // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/in-trait/issue-102138.rs b/tests/ui/async-await/in-trait/issue-102138.rs index f61b34ed99e00..ced30b7e4e4b9 100644 --- a/tests/ui/async-await/in-trait/issue-102138.rs +++ b/tests/ui/async-await/in-trait/issue-102138.rs @@ -1,5 +1,7 @@ // check-pass // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/in-trait/issue-102219.rs b/tests/ui/async-await/in-trait/issue-102219.rs index 9a35f6515cb1a..f3fdfa3459aea 100644 --- a/tests/ui/async-await/in-trait/issue-102219.rs +++ b/tests/ui/async-await/in-trait/issue-102219.rs @@ -1,6 +1,8 @@ // compile-flags:--crate-type=lib // edition:2021 // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] From b82d6a2e9ee96d4c001e2c3ad74d8dc9521ac5ac Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 Mar 2023 11:18:38 -0300 Subject: [PATCH 090/124] Run existing impl trait in traits tests using -Zlower-impl-trait-in-trait-to-assoc-ty --- .../ui/impl-trait/in-trait/deep-match-works.rs | 6 +++++- ...p-match.stderr => deep-match.current.stderr} | 4 ++-- .../impl-trait/in-trait/deep-match.next.stderr | 15 +++++++++++++++ tests/ui/impl-trait/in-trait/deep-match.rs | 9 +++++++-- ...fault-method-binder-shifting.current.stderr} | 2 +- .../default-method-binder-shifting.next.stderr | 11 +++++++++++ .../in-trait/default-method-binder-shifting.rs | 2 ++ tests/ui/impl-trait/in-trait/encode.rs | 2 ++ ... => opaque-in-impl-is-opaque.current.stderr} | 2 +- .../opaque-in-impl-is-opaque.next.stderr | 17 +++++++++++++++++ .../in-trait/opaque-in-impl-is-opaque.rs | 3 +++ tests/ui/impl-trait/in-trait/reveal.rs | 2 ++ ...stderr => signature-mismatch.current.stderr} | 2 +- .../in-trait/signature-mismatch.next.stderr | 16 ++++++++++++++++ .../impl-trait/in-trait/signature-mismatch.rs | 2 ++ .../in-trait/specialization-substs-remap.rs | 2 ++ tests/ui/impl-trait/in-trait/success.rs | 2 ++ 17 files changed, 91 insertions(+), 8 deletions(-) rename tests/ui/impl-trait/in-trait/{deep-match.stderr => deep-match.current.stderr} (86%) create mode 100644 tests/ui/impl-trait/in-trait/deep-match.next.stderr rename tests/ui/impl-trait/in-trait/{default-method-binder-shifting.stderr => default-method-binder-shifting.current.stderr} (89%) create mode 100644 tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr rename tests/ui/impl-trait/in-trait/{opaque-in-impl-is-opaque.stderr => opaque-in-impl-is-opaque.current.stderr} (91%) create mode 100644 tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr rename tests/ui/impl-trait/in-trait/{signature-mismatch.stderr => signature-mismatch.current.stderr} (96%) create mode 100644 tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr diff --git a/tests/ui/impl-trait/in-trait/deep-match-works.rs b/tests/ui/impl-trait/in-trait/deep-match-works.rs index 772da845ee1f7..5c9d2e356fc70 100644 --- a/tests/ui/impl-trait/in-trait/deep-match-works.rs +++ b/tests/ui/impl-trait/in-trait/deep-match-works.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] @@ -10,7 +12,9 @@ trait Foo { } impl Foo for () { - fn bar() -> Wrapper { Wrapper(0) } + fn bar() -> Wrapper { + Wrapper(0) + } } fn main() {} diff --git a/tests/ui/impl-trait/in-trait/deep-match.stderr b/tests/ui/impl-trait/in-trait/deep-match.current.stderr similarity index 86% rename from tests/ui/impl-trait/in-trait/deep-match.stderr rename to tests/ui/impl-trait/in-trait/deep-match.current.stderr index 3eba419c0a3fd..400db20c79c92 100644 --- a/tests/ui/impl-trait/in-trait/deep-match.stderr +++ b/tests/ui/impl-trait/in-trait/deep-match.current.stderr @@ -1,7 +1,7 @@ error[E0053]: method `bar` has an incompatible return type for trait - --> $DIR/deep-match.rs:11:17 + --> $DIR/deep-match.rs:14:17 | -LL | fn bar() -> i32 { 0 } +LL | fn bar() -> i32 { | ^^^ | | | expected `Wrapper<_>`, found `i32` diff --git a/tests/ui/impl-trait/in-trait/deep-match.next.stderr b/tests/ui/impl-trait/in-trait/deep-match.next.stderr new file mode 100644 index 0000000000000..400db20c79c92 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/deep-match.next.stderr @@ -0,0 +1,15 @@ +error[E0053]: method `bar` has an incompatible return type for trait + --> $DIR/deep-match.rs:14:17 + | +LL | fn bar() -> i32 { + | ^^^ + | | + | expected `Wrapper<_>`, found `i32` + | return type in trait + | + = note: expected struct `Wrapper<_>` + found type `i32` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-trait/deep-match.rs b/tests/ui/impl-trait/in-trait/deep-match.rs index a6385147c3ae7..413d054e148a6 100644 --- a/tests/ui/impl-trait/in-trait/deep-match.rs +++ b/tests/ui/impl-trait/in-trait/deep-match.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] @@ -8,8 +11,10 @@ trait Foo { } impl Foo for () { - fn bar() -> i32 { 0 } - //~^ ERROR method `bar` has an incompatible return type for trait + fn bar() -> i32 { + //~^ ERROR method `bar` has an incompatible return type for trait + 0 + } } fn main() {} diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.stderr b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.current.stderr similarity index 89% rename from tests/ui/impl-trait/in-trait/default-method-binder-shifting.stderr rename to tests/ui/impl-trait/in-trait/default-method-binder-shifting.current.stderr index 7c7ebcdb7e717..a0c0589b9a1c0 100644 --- a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.stderr +++ b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.current.stderr @@ -1,5 +1,5 @@ warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-method-binder-shifting.rs:3:12 + --> $DIR/default-method-binder-shifting.rs:5:12 | LL | #![feature(return_position_impl_trait_in_trait)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr new file mode 100644 index 0000000000000..a0c0589b9a1c0 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr @@ -0,0 +1,11 @@ +warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/default-method-binder-shifting.rs:5:12 + | +LL | #![feature(return_position_impl_trait_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs index 5cf90c5d93c24..75b0ec939847a 100644 --- a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs +++ b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] //~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete diff --git a/tests/ui/impl-trait/in-trait/encode.rs b/tests/ui/impl-trait/in-trait/encode.rs index efb9f6498ba6d..98aaf4a6553f5 100644 --- a/tests/ui/impl-trait/in-trait/encode.rs +++ b/tests/ui/impl-trait/in-trait/encode.rs @@ -1,5 +1,7 @@ // build-pass // compile-flags: --crate-type=lib +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr similarity index 91% rename from tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr rename to tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr index 15edda4834015..a57653b2c9ed7 100644 --- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr +++ b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/opaque-in-impl-is-opaque.rs:17:19 + --> $DIR/opaque-in-impl-is-opaque.rs:20:19 | LL | fn bar(&self) -> impl Display { | ------------ the found opaque type diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr new file mode 100644 index 0000000000000..a57653b2c9ed7 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/opaque-in-impl-is-opaque.rs:20:19 + | +LL | fn bar(&self) -> impl Display { + | ------------ the found opaque type +... +LL | let x: &str = ().bar(); + | ---- ^^^^^^^^ expected `&str`, found opaque type + | | + | expected due to this + | + = note: expected reference `&str` + found opaque type `impl std::fmt::Display` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs index 3ac264e8ebac5..c07ece15a8324 100644 --- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs +++ b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/impl-trait/in-trait/reveal.rs b/tests/ui/impl-trait/in-trait/reveal.rs index d6ede1cc495c6..1f42ec744dbe8 100644 --- a/tests/ui/impl-trait/in-trait/reveal.rs +++ b/tests/ui/impl-trait/in-trait/reveal.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr similarity index 96% rename from tests/ui/impl-trait/in-trait/signature-mismatch.stderr rename to tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr index c4fcaabe44619..eba270af7f0ee 100644 --- a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr @@ -1,5 +1,5 @@ error: `impl` item signature doesn't match `trait` item signature - --> $DIR/signature-mismatch.rs:15:5 + --> $DIR/signature-mismatch.rs:17:5 | LL | fn async_fn(&self, buff: &[u8]) -> impl Future>; | ----------------------------------------------------------------- expected `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '3` diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr new file mode 100644 index 0000000000000..eba270af7f0ee --- /dev/null +++ b/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr @@ -0,0 +1,16 @@ +error: `impl` item signature doesn't match `trait` item signature + --> $DIR/signature-mismatch.rs:17:5 + | +LL | fn async_fn(&self, buff: &[u8]) -> impl Future>; + | ----------------------------------------------------------------- expected `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '3` +... +LL | fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future> + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '2` + | + = note: expected signature `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '3` + found signature `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '2` + = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output + +error: aborting due to previous error + diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.rs b/tests/ui/impl-trait/in-trait/signature-mismatch.rs index 90682631aa032..38c902a97a980 100644 --- a/tests/ui/impl-trait/in-trait/signature-mismatch.rs +++ b/tests/ui/impl-trait/in-trait/signature-mismatch.rs @@ -1,4 +1,6 @@ // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs index c9ee877db8ec5..dbc5d38f19292 100644 --- a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs +++ b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(specialization)] #![feature(return_position_impl_trait_in_trait)] diff --git a/tests/ui/impl-trait/in-trait/success.rs b/tests/ui/impl-trait/in-trait/success.rs index 4cbe682b46f73..0e69e0490c776 100644 --- a/tests/ui/impl-trait/in-trait/success.rs +++ b/tests/ui/impl-trait/in-trait/success.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] From b2f3198608eae7f24eecd930e6467f0cfb3cffd1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 7 Mar 2023 13:31:28 -0300 Subject: [PATCH 091/124] Filter out RPITITs in astconv when checking for missing associated types --- .../rustc_hir_analysis/src/astconv/mod.rs | 1 + ...140.stderr => issue-102140.current.stderr} | 6 ++-- .../in-trait/issue-102140.next.stderr | 33 +++++++++++++++++++ tests/ui/impl-trait/in-trait/issue-102140.rs | 3 ++ 4 files changed, 40 insertions(+), 3 deletions(-) rename tests/ui/impl-trait/in-trait/{issue-102140.stderr => issue-102140.current.stderr} (91%) create mode 100644 tests/ui/impl-trait/in-trait/issue-102140.next.stderr diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 3cd4c4afe866e..f830269b45dae 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1440,6 +1440,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.associated_items(pred.def_id()) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| tcx.opt_rpitit_info(item.def_id).is_none()) .map(|item| item.def_id), ); } diff --git a/tests/ui/impl-trait/in-trait/issue-102140.stderr b/tests/ui/impl-trait/in-trait/issue-102140.current.stderr similarity index 91% rename from tests/ui/impl-trait/in-trait/issue-102140.stderr rename to tests/ui/impl-trait/in-trait/issue-102140.current.stderr index 18bb63745d7a5..7aa7880e25883 100644 --- a/tests/ui/impl-trait/in-trait/issue-102140.stderr +++ b/tests/ui/impl-trait/in-trait/issue-102140.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:23:22 + --> $DIR/issue-102140.rs:26:22 | LL | MyTrait::foo(&self) | ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` @@ -13,7 +13,7 @@ LL + MyTrait::foo(self) | error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:23:9 + --> $DIR/issue-102140.rs:26:9 | LL | MyTrait::foo(&self) | ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` @@ -21,7 +21,7 @@ LL | MyTrait::foo(&self) = help: the trait `MyTrait` is implemented for `Outer` error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:23:9 + --> $DIR/issue-102140.rs:26:9 | LL | MyTrait::foo(&self) | ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` diff --git a/tests/ui/impl-trait/in-trait/issue-102140.next.stderr b/tests/ui/impl-trait/in-trait/issue-102140.next.stderr new file mode 100644 index 0000000000000..7aa7880e25883 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/issue-102140.next.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied + --> $DIR/issue-102140.rs:26:22 + | +LL | MyTrait::foo(&self) + | ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` + | | + | required by a bound introduced by this call + | +help: consider removing the leading `&`-reference + | +LL - MyTrait::foo(&self) +LL + MyTrait::foo(self) + | + +error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied + --> $DIR/issue-102140.rs:26:9 + | +LL | MyTrait::foo(&self) + | ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` + | + = help: the trait `MyTrait` is implemented for `Outer` + +error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied + --> $DIR/issue-102140.rs:26:9 + | +LL | MyTrait::foo(&self) + | ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` + | + = help: the trait `MyTrait` is implemented for `Outer` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/issue-102140.rs b/tests/ui/impl-trait/in-trait/issue-102140.rs index be1e012acb185..4dcac4f5b0eac 100644 --- a/tests/ui/impl-trait/in-trait/issue-102140.rs +++ b/tests/ui/impl-trait/in-trait/issue-102140.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] From fa421ec454dfd2a5e8d4c2aa17284e80043a6989 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 7 Mar 2023 13:44:14 -0300 Subject: [PATCH 092/124] Filter out RPITITs in object_safety_violations_for_trait --- .../src/traits/object_safety.rs | 1 + ...ty.stderr => object-safety.current.stderr} | 6 ++--- .../in-trait/object-safety.next.stderr | 27 +++++++++++++++++++ .../ui/async-await/in-trait/object-safety.rs | 2 ++ 4 files changed, 33 insertions(+), 3 deletions(-) rename tests/ui/async-await/in-trait/{object-safety.stderr => object-safety.current.stderr} (91%) create mode 100644 tests/ui/async-await/in-trait/object-safety.next.stderr diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 4eacb5211f760..4b06304f40292 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -157,6 +157,7 @@ fn object_safety_violations_for_trait( .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) .filter(|item| !tcx.generics_of(item.def_id).params.is_empty()) + .filter(|item| tcx.opt_rpitit_info(item.def_id).is_none()) .map(|item| { let ident = item.ident(tcx); ObjectSafetyViolation::GAT(ident.name, ident.span) diff --git a/tests/ui/async-await/in-trait/object-safety.stderr b/tests/ui/async-await/in-trait/object-safety.current.stderr similarity index 91% rename from tests/ui/async-await/in-trait/object-safety.stderr rename to tests/ui/async-await/in-trait/object-safety.current.stderr index 0b318f71f395d..90e049a99606f 100644 --- a/tests/ui/async-await/in-trait/object-safety.stderr +++ b/tests/ui/async-await/in-trait/object-safety.current.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/object-safety.rs:3:12 + --> $DIR/object-safety.rs:5:12 | LL | #![feature(async_fn_in_trait)] | ^^^^^^^^^^^^^^^^^ @@ -8,13 +8,13 @@ LL | #![feature(async_fn_in_trait)] = note: `#[warn(incomplete_features)]` on by default error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:11:12 + --> $DIR/object-safety.rs:13:12 | LL | let x: &dyn Foo = todo!(); | ^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:7:14 + --> $DIR/object-safety.rs:9:14 | LL | trait Foo { | --- this trait cannot be made into an object... diff --git a/tests/ui/async-await/in-trait/object-safety.next.stderr b/tests/ui/async-await/in-trait/object-safety.next.stderr new file mode 100644 index 0000000000000..90e049a99606f --- /dev/null +++ b/tests/ui/async-await/in-trait/object-safety.next.stderr @@ -0,0 +1,27 @@ +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/object-safety.rs:5:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:13:12 + | +LL | let x: &dyn Foo = todo!(); + | ^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:9:14 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | async fn foo(&self); + | ^^^ ...because method `foo` is `async` + = help: consider moving `foo` to another trait + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/in-trait/object-safety.rs b/tests/ui/async-await/in-trait/object-safety.rs index a8bc35f7e0c59..f67286a20a244 100644 --- a/tests/ui/async-await/in-trait/object-safety.rs +++ b/tests/ui/async-await/in-trait/object-safety.rs @@ -1,4 +1,6 @@ // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] //~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes From 8b9344acc3cc7f63ce2294c1482d7e386e812b6e Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 Mar 2023 13:07:20 -0300 Subject: [PATCH 093/124] Fix object safety checks for new RPITITs --- .../src/traits/object_safety.rs | 5 +- ...ty.stderr => object-safety.current.stderr} | 12 ++--- .../in-trait/object-safety.next.stderr | 50 +++++++++++++++++++ tests/ui/impl-trait/in-trait/object-safety.rs | 3 ++ 4 files changed, 61 insertions(+), 9 deletions(-) rename tests/ui/impl-trait/in-trait/{object-safety.stderr => object-safety.current.stderr} (93%) create mode 100644 tests/ui/impl-trait/in-trait/object-safety.next.stderr diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 4b06304f40292..a5def4151bfda 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -13,7 +13,6 @@ use super::{elaborate_predicates, elaborate_trait_ref}; use crate::infer::TyCtxtInferExt; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, Obligation, ObligationCause}; -use hir::def::DefKind; use rustc_errors::{DelayDm, FatalError, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -855,7 +854,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable>>( } } ty::Alias(ty::Projection, ref data) - if self.tcx.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder => + if self.tcx.is_impl_trait_in_trait(data.def_id) => { // We'll deny these later in their own pass ControlFlow::Continue(()) @@ -922,7 +921,7 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>( ty.skip_binder().walk().find_map(|arg| { if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Alias(ty::Projection, proj) = ty.kind() - && tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder + && tcx.is_impl_trait_in_trait(proj.def_id) { Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.def_id))) } else { diff --git a/tests/ui/impl-trait/in-trait/object-safety.stderr b/tests/ui/impl-trait/in-trait/object-safety.current.stderr similarity index 93% rename from tests/ui/impl-trait/in-trait/object-safety.stderr rename to tests/ui/impl-trait/in-trait/object-safety.current.stderr index ca0e760ff6d35..b7f2b019a7765 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.stderr +++ b/tests/ui/impl-trait/in-trait/object-safety.current.stderr @@ -1,11 +1,11 @@ error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:17:33 + --> $DIR/object-safety.rs:20:33 | LL | let i = Box::new(42_u32) as Box; | ^^^^^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:7:22 + --> $DIR/object-safety.rs:10:22 | LL | trait Foo { | --- this trait cannot be made into an object... @@ -14,13 +14,13 @@ LL | fn baz(&self) -> impl Debug; = help: consider moving `baz` to another trait error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:20:13 + --> $DIR/object-safety.rs:23:13 | LL | let s = i.baz(); | ^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:7:22 + --> $DIR/object-safety.rs:10:22 | LL | trait Foo { | --- this trait cannot be made into an object... @@ -29,13 +29,13 @@ LL | fn baz(&self) -> impl Debug; = help: consider moving `baz` to another trait error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:17:13 + --> $DIR/object-safety.rs:20:13 | LL | let i = Box::new(42_u32) as Box; | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:7:22 + --> $DIR/object-safety.rs:10:22 | LL | trait Foo { | --- this trait cannot be made into an object... diff --git a/tests/ui/impl-trait/in-trait/object-safety.next.stderr b/tests/ui/impl-trait/in-trait/object-safety.next.stderr new file mode 100644 index 0000000000000..b7f2b019a7765 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/object-safety.next.stderr @@ -0,0 +1,50 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:20:33 + | +LL | let i = Box::new(42_u32) as Box; + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:10:22 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:23:13 + | +LL | let s = i.baz(); + | ^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:10:22 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:20:13 + | +LL | let i = Box::new(42_u32) as Box; + | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:10:22 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + = note: required for `Box` to implement `CoerceUnsized>` + = note: required by cast to type `Box` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/in-trait/object-safety.rs b/tests/ui/impl-trait/in-trait/object-safety.rs index dd35b9a2d8a75..016a0aaae4b6e 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.rs +++ b/tests/ui/impl-trait/in-trait/object-safety.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] From 0b96fee34315b75c8f05ce338d3beb6c85772056 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 12 Mar 2023 12:57:40 -0700 Subject: [PATCH 094/124] Add a codegen test to confirm this fixes 106369 --- tests/codegen/issues/issue-106369.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/codegen/issues/issue-106369.rs diff --git a/tests/codegen/issues/issue-106369.rs b/tests/codegen/issues/issue-106369.rs new file mode 100644 index 0000000000000..3fe7be4f1442e --- /dev/null +++ b/tests/codegen/issues/issue-106369.rs @@ -0,0 +1,15 @@ +// compile-flags: -O +// ignore-debug (the extra assertions get in the way) + +#![crate_type = "lib"] + +// From + +// CHECK-LABEL: @issue_106369( +#[no_mangle] +pub unsafe fn issue_106369(ptr: *const &i32) -> bool { + // CHECK-NOT: icmp + // CHECK: ret i1 true + // CHECK-NOT: icmp + Some(std::ptr::read(ptr)).is_some() +} From 1f70bb8c43054d3948ffb579ba3809822a889c62 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 12 Mar 2023 13:23:22 -0700 Subject: [PATCH 095/124] Add a codegen test to confirm this fixes 73258 --- tests/codegen/issues/issue-73258.rs | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/codegen/issues/issue-73258.rs diff --git a/tests/codegen/issues/issue-73258.rs b/tests/codegen/issues/issue-73258.rs new file mode 100644 index 0000000000000..0134f929b2961 --- /dev/null +++ b/tests/codegen/issues/issue-73258.rs @@ -0,0 +1,38 @@ +// compile-flags: -O +// ignore-debug (the extra assertions get in the way) + +#![crate_type = "lib"] + +// Adapted from + +#[derive(Clone, Copy)] +#[repr(u8)] +pub enum Foo { + A, B, C, D, +} + +// CHECK-LABEL: @issue_73258( +#[no_mangle] +pub unsafe fn issue_73258(ptr: *const Foo) -> Foo { + // CHECK-NOT: icmp + // CHECK-NOT: call + // CHECK-NOT: br + // CHECK-NOT: select + + // CHECK: %[[R:.+]] = load i8 + // CHECK-SAME: !range ! + + // CHECK-NOT: icmp + // CHECK-NOT: call + // CHECK-NOT: br + // CHECK-NOT: select + + // CHECK: ret i8 %[[R]] + + // CHECK-NOT: icmp + // CHECK-NOT: call + // CHECK-NOT: br + // CHECK-NOT: select + let k: Option = Some(ptr.read()); + return k.unwrap(); +} From 87696fd5a1a1b7cd75cd9a66896deae0ab56cfb5 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 12 Mar 2023 15:52:34 -0700 Subject: [PATCH 096/124] Add a better approach comment in `ptr::read` to justify the intrinsic --- library/core/src/ptr/mod.rs | 43 +++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 04b67a56db59b..86929e2c4889c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1135,17 +1135,31 @@ pub const unsafe fn replace(dst: *mut T, mut src: T) -> T { #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn read(src: *const T) -> T { - // We are calling the intrinsics directly to avoid function calls in the generated code - // as `intrinsics::copy_nonoverlapping` is a wrapper function. - #[cfg(bootstrap)] - extern "rust-intrinsic" { - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] - fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); - } + // It would be semantically correct to implement this via `copy_nonoverlapping` + // and `MaybeUninit`, as was done before PR #109035. + + // However, it switched to intrinsic that lowers to `_0 = *src` in MIR in + // order to address a few implementation issues: + // + // - Using `MaybeUninit::assume_init` after a `copy_nonoverlapping` was not + // turning the untyped copy into a typed load. As such, the generated + // `load` in LLVM didn't get various metadata, such as `!range` (#73258), + // `!nonnull`, and `!noundef`, resulting in poorer optimization. + // - Going through the extra local resulted in multiple extra copies, even + // in optimized MIR. (Ignoring StorageLive/Dead, the intrinsic is one + // MIR statement, while the previous implementation was eight.) LLVM + // could sometimes optimize them away, but because `read` is at the core + // of so many things, not having them in the first place improves what we + // hand off to the backend. For example, `mem::replace::` previously + // emitted 4 `alloca` and 6 `memcpy`s, but is now 1 `alloc` and 3 `memcpy`s. + // - In general, this approach keeps us from getting any more bugs (like + // #106369) that boil down to "`read(p)` is worse than `*p`", as this + // makes them look identical to the backend (or other MIR consumers). + // + // Future enhancements to MIR optimizations might well allow this to return + // to the previous implementation, rather than using an intrinsic. // SAFETY: the caller must guarantee that `src` is valid for reads. - // `src` cannot overlap `tmp` because `tmp` was just allocated on - // the stack as a separate allocated object. unsafe { assert_unsafe_precondition!( "ptr::read requires that the pointer argument is aligned and non-null", @@ -1154,14 +1168,21 @@ pub const unsafe fn read(src: *const T) -> T { #[cfg(bootstrap)] { + // We are calling the intrinsics directly to avoid function calls in the + // generated code as `intrinsics::copy_nonoverlapping` is a wrapper function. + extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] + fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); + } + + // `src` cannot overlap `tmp` because `tmp` was just allocated on + // the stack as a separate allocated object. let mut tmp = MaybeUninit::::uninit(); copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); tmp.assume_init() } #[cfg(not(bootstrap))] { - // This uses a dedicated intrinsic, not `copy_nonoverlapping`, - // so that it gets a *typed* copy, not an *untyped* one. crate::intrinsics::read_via_copy(src) } } From db6fb616b9b94266b7941517e77e6ab824ca5cbf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 13 Mar 2023 12:23:45 +0100 Subject: [PATCH 097/124] Rustup to rustc 1.70.0-nightly (7b4f48927 2023-03-12) --- build_sysroot/Cargo.lock | 4 ++-- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index 1eadc8a4db6e1..f21507629911a 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2fbf11d629e314a85bc4d7348ee388d98ad0e8eb53182f3e5a17bc63613acd2" +checksum = "9fc9c2080d347a2c316518840ac9194644a9993dfa1e9778ef38979a339f5d8b" dependencies = [ "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index 1c2e2f90676b9..f86eb7a2b53d8 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-03-10" +channel = "nightly-2023-03-13" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 9df8da8e04d04492d57603d69d1b9c330b4424f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 6 Mar 2023 12:32:45 +0000 Subject: [PATCH 098/124] fix ignore header in MSVC test --- tests/ui/panic-runtime/unwind-tables-target-required.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/panic-runtime/unwind-tables-target-required.rs b/tests/ui/panic-runtime/unwind-tables-target-required.rs index 3abb52b675a60..f2145c2bfe756 100644 --- a/tests/ui/panic-runtime/unwind-tables-target-required.rs +++ b/tests/ui/panic-runtime/unwind-tables-target-required.rs @@ -1,7 +1,7 @@ // Tests that the compiler errors if the user tries to turn off unwind tables // when they are required. // -// only-x86_64-windows-msvc +// only-x86_64-pc-windows-msvc // compile-flags: -C force-unwind-tables=no // // error-pattern: target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`. From 877530cf1a950cf82ca0acc6e66ae9eadb1267d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 13 Mar 2023 14:01:25 +0100 Subject: [PATCH 099/124] fix error pattern --- tests/ui/panic-runtime/unwind-tables-target-required.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/panic-runtime/unwind-tables-target-required.rs b/tests/ui/panic-runtime/unwind-tables-target-required.rs index f2145c2bfe756..be2cbf6586779 100644 --- a/tests/ui/panic-runtime/unwind-tables-target-required.rs +++ b/tests/ui/panic-runtime/unwind-tables-target-required.rs @@ -4,7 +4,7 @@ // only-x86_64-pc-windows-msvc // compile-flags: -C force-unwind-tables=no // -// error-pattern: target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`. +// error-pattern: target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no` pub fn main() { } From 956bebb07b641b1d9c1b04255f9a190e8f00a146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 13 Mar 2023 14:01:48 +0100 Subject: [PATCH 100/124] remove need for test expectations --- tests/ui/panic-runtime/unwind-tables-target-required.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/panic-runtime/unwind-tables-target-required.rs b/tests/ui/panic-runtime/unwind-tables-target-required.rs index be2cbf6586779..5a90b314a6ed1 100644 --- a/tests/ui/panic-runtime/unwind-tables-target-required.rs +++ b/tests/ui/panic-runtime/unwind-tables-target-required.rs @@ -4,6 +4,7 @@ // only-x86_64-pc-windows-msvc // compile-flags: -C force-unwind-tables=no // +// dont-check-compiler-stderr // error-pattern: target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no` pub fn main() { From 0bb876ebe76dee4c3f00fcd3c581d87ad67940ef Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 13 Mar 2023 21:35:15 +0000 Subject: [PATCH 101/124] Layout of `&dyn Trait<[type error]>` is still wide --- compiler/rustc_middle/src/ty/layout.rs | 6 +++++- compiler/rustc_ty_utils/src/layout.rs | 6 +++++- tests/ui/layout/transmute-to-tail-with-err.rs | 8 ++++++++ tests/ui/layout/transmute-to-tail-with-err.stderr | 14 ++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/ui/layout/transmute-to-tail-with-err.rs create mode 100644 tests/ui/layout/transmute-to-tail-with-err.stderr diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 254ffc33c96f0..42fb5d031bbc9 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -730,7 +730,11 @@ where */ }; - let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { + let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() + // Projection eagerly bails out when the pointee references errors, + // fall back to structurally deducing metadata. + && !pointee.references_error() + { let metadata = tcx.normalize_erasing_regions( cx.param_env(), tcx.mk_projection(metadata_def_id, [pointee]), diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index e3132fcc4c412..1788f544a7f9a 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -156,7 +156,11 @@ fn layout_of_uncached<'tcx>( let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env); - let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { + let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() + // Projection eagerly bails out when the pointee references errors, + // fall back to structurally deducing metadata. + && !pointee.references_error() + { let metadata_ty = tcx.normalize_erasing_regions( param_env, tcx.mk_projection(metadata_def_id, [pointee]), diff --git a/tests/ui/layout/transmute-to-tail-with-err.rs b/tests/ui/layout/transmute-to-tail-with-err.rs new file mode 100644 index 0000000000000..6753ce15ed158 --- /dev/null +++ b/tests/ui/layout/transmute-to-tail-with-err.rs @@ -0,0 +1,8 @@ +trait Trait {} + +struct Bar(Box>); +//~^ ERROR cannot find type `T` in this scope + +fn main() { + let x: Bar = unsafe { std::mem::transmute(()) }; +} diff --git a/tests/ui/layout/transmute-to-tail-with-err.stderr b/tests/ui/layout/transmute-to-tail-with-err.stderr new file mode 100644 index 0000000000000..97ab59c398a3b --- /dev/null +++ b/tests/ui/layout/transmute-to-tail-with-err.stderr @@ -0,0 +1,14 @@ +error[E0412]: cannot find type `T` in this scope + --> $DIR/transmute-to-tail-with-err.rs:3:26 + | +LL | struct Bar(Box>); + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | struct Bar(Box>); + | +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. From 8a535700087b3f09b60173ea462f6e872baa7486 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 13 Mar 2023 22:38:37 +0000 Subject: [PATCH 102/124] Don't ICE for late-bound consts across AnonConstBoundary --- .../src/collect/resolve_bound_vars.rs | 14 +++++++------- .../capture-late-ct-in-anon.rs | 11 +++++++++++ .../capture-late-ct-in-anon.stderr | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs create mode 100644 tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index e9963e67741ba..465ae047de373 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1427,25 +1427,25 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { if let ResolvedArg::LateBound(..) = def && crossed_anon_const { let use_span = self.tcx.hir().span(hir_id); let def_span = self.tcx.def_span(param_def_id); - match self.tcx.def_kind(param_def_id) { + let guar = match self.tcx.def_kind(param_def_id) { DefKind::ConstParam => { self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Const { use_span, def_span, - }); + }) } DefKind::TyParam => { self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Type { use_span, def_span, - }); + }) } _ => unreachable!(), - } - return; + }; + self.map.defs.insert(hir_id, ResolvedArg::Error(guar)); + } else { + self.map.defs.insert(hir_id, def); } - - self.map.defs.insert(hir_id, def); return; } diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs new file mode 100644 index 0000000000000..91c6dfb8e0a92 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs @@ -0,0 +1,11 @@ +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +fn b() +where + for [(); C]: Copy, + //~^ ERROR cannot capture late-bound const parameter in a constant +{ +} + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr new file mode 100644 index 0000000000000..69bb605bf41ca --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr @@ -0,0 +1,19 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/capture-late-ct-in-anon.rs:1:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: cannot capture late-bound const parameter in a constant + --> $DIR/capture-late-ct-in-anon.rs:6:30 + | +LL | for [(); C]: Copy, + | -------------- ^ + | | + | parameter defined here + +error: aborting due to previous error; 1 warning emitted + From a4692f46c42b315921d21571ca3568c84a87e647 Mon Sep 17 00:00:00 2001 From: Mu001999 Date: Tue, 14 Mar 2023 11:22:45 +0800 Subject: [PATCH 103/124] Create dir for build_triple --- src/bootstrap/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 22ddf87221595..f136690592d72 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -495,6 +495,7 @@ impl Build { // Make a symbolic link so we can use a consistent directory in the documentation. let build_triple = build.out.join(&build.build.triple); + t!(fs::create_dir_all(&build_triple)); let host = build.out.join("host"); if let Err(e) = symlink_dir(&build.config, &build_triple, &host) { if e.kind() != ErrorKind::AlreadyExists { From b535da6841c8dec255a1734b9ac1ed9e9e7c5e25 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 Mar 2023 17:57:54 -0300 Subject: [PATCH 104/124] Get impl defaultness using query --- compiler/rustc_metadata/src/rmeta/encoder.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index bbab8a62a2bce..59e2e57e6c25a 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1356,13 +1356,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_info_for_impl_item({:?})", def_id); let tcx = self.tcx; - let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local()); - self.tables.impl_defaultness.set_some(def_id.index, ast_item.defaultness); + let defaultness = self.tcx.impl_defaultness(def_id.expect_local()); + self.tables.impl_defaultness.set_some(def_id.index, defaultness); let impl_item = self.tcx.associated_item(def_id); self.tables.assoc_container.set_some(def_id.index, impl_item.container); match impl_item.kind { ty::AssocKind::Fn => { + let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local()); let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() }; self.tables.asyncness.set_some(def_id.index, sig.header.asyncness); record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); From a4e40370d018bf2a5c5a9713a7532638838f740d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 Mar 2023 17:59:06 -0300 Subject: [PATCH 105/124] Make fns from other crates with RPITIT work --- compiler/rustc_hir/src/definitions.rs | 6 +++++- compiler/rustc_ty_utils/src/assoc.rs | 6 ++++++ tests/ui/impl-trait/in-trait/foreign.rs | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 8ceb176491b6f..3c4fc9cb530a4 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -404,8 +404,12 @@ impl DefPathData { match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), + // We use this name when collecting `ModChild`s. + // FIXME this could probably be removed with some refactoring to the name resolver. + ImplTraitAssocTy => Some(kw::Empty), + Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst - | ImplTrait | ImplTraitAssocTy => None, + | ImplTrait => None, } } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 867974749d5fe..a28161245384c 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -328,6 +328,9 @@ fn impl_associated_item_for_impl_trait_in_trait( // `opt_local_def_id_to_hir_id` with `None`. impl_assoc_ty.opt_local_def_id_to_hir_id(None); + // Copy span of the opaque. + impl_assoc_ty.def_ident_span(Some(span)); + impl_assoc_ty.associated_item(ty::AssocItem { name: kw::Empty, kind: ty::AssocKind::Type, @@ -342,6 +345,9 @@ fn impl_associated_item_for_impl_trait_in_trait( // extra predicates to assume. impl_assoc_ty.param_env(tcx.param_env(impl_fn_def_id)); + // Copy visility of the containing function. + impl_assoc_ty.visibility(tcx.visibility(impl_fn_def_id)); + // Copy impl_defaultness of the containing function. impl_assoc_ty.impl_defaultness(tcx.impl_defaultness(impl_fn_def_id)); diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs index 6341f5b428429..df77372aabdfc 100644 --- a/tests/ui/impl-trait/in-trait/foreign.rs +++ b/tests/ui/impl-trait/in-trait/foreign.rs @@ -1,5 +1,7 @@ // check-pass // aux-build: rpitit.rs +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next extern crate rpitit; From 4824363e67b62aa5e96fec5873d373cdc2cac96a Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 Mar 2023 23:42:08 -0300 Subject: [PATCH 106/124] Remove some direct calls to local_def_id_to_hir_id on diagnostics --- compiler/rustc_middle/src/hir/map/mod.rs | 4 ++-- .../src/traits/error_reporting/on_unimplemented.rs | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 746cf48858932..8a4c10cd71c03 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -316,7 +316,7 @@ impl<'hir> Map<'hir> { /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found. #[inline] pub fn find_by_def_id(self, id: LocalDefId) -> Option> { - self.find(self.local_def_id_to_hir_id(id)) + self.find(self.tcx.opt_local_def_id_to_hir_id(id)?) } /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found. @@ -333,7 +333,7 @@ impl<'hir> Map<'hir> { } pub fn get_if_local(self, id: DefId) -> Option> { - id.as_local().and_then(|id| self.find(self.local_def_id_to_hir_id(id))) + id.as_local().and_then(|id| self.find(self.tcx.opt_local_def_id_to_hir_id(id)?)) } pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index b3bf9ad599acc..277926688e21d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -144,6 +144,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, obligation: &PredicateObligation<'tcx>, ) -> OnUnimplementedNote { + if self.tcx.opt_rpitit_info(obligation.cause.body_id.to_def_id()).is_some() { + return OnUnimplementedNote::default(); + } + let (def_id, substs) = self .impl_similar_to(trait_ref, obligation) .unwrap_or_else(|| (trait_ref.def_id(), trait_ref.skip_binder().substs)); From 6a2a6feca87fe52aa7c3bb4ab54a2b98e7459cd0 Mon Sep 17 00:00:00 2001 From: Maciej Wasilewski <52935969+MaciejWas@users.noreply.github.com> Date: Tue, 14 Mar 2023 14:12:47 +0100 Subject: [PATCH 107/124] Emit "modifies receiver" diagnostic when no method is found If no method is found when checking method call, we check if we called a method with signature (&mut T, ...) -> (). If this is the case then we emit a diagnostic message --- compiler/rustc_hir_typeck/src/demand.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 81 +++++++++++++------ .../rustc_hir_typeck/src/method/suggest.rs | 7 ++ .../chain-method-call-mutation-in-place.rs | 6 +- ...chain-method-call-mutation-in-place.stderr | 37 ++++++++- 5 files changed, 102 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 7ba57b3b7a266..0ec10dc9ea32d 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.annotate_expected_due_to_let_ty(err, expr, error); self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error); self.note_type_is_not_clone(err, expected, expr_ty, expr); - self.note_internal_mutation_in_method(err, expr, expected, expr_ty); + self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty); self.check_for_range_as_method_call(err, expr, expr_ty, expected); self.check_for_binding_assigned_block_without_tail_expression(err, expr, expr_ty, expected); self.check_wrong_return_type_due_to_generic_arg(err, expr, expr_ty); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2075537cad71f..578e5b0104657 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -955,44 +955,75 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, - expected: Ty<'tcx>, + expected: Option>, found: Ty<'tcx>, ) { if found != self.tcx.types.unit { return; } - if let ExprKind::MethodCall(path_segment, rcvr, ..) = expr.kind { - if self - .typeck_results + + let ExprKind::MethodCall(path_segment, rcvr, ..) = expr.kind else { + return; + }; + + let rcvr_has_the_expected_type = self + .typeck_results + .borrow() + .expr_ty_adjusted_opt(rcvr) + .and_then(|ty| expected.map(|expected_ty| expected_ty.peel_refs() == ty.peel_refs())) + .unwrap_or(false); + + let prev_call_mutates_and_returns_unit = || { + self.typeck_results .borrow() - .expr_ty_adjusted_opt(rcvr) - .map_or(true, |ty| expected.peel_refs() != ty.peel_refs()) - { - return; - } - let mut sp = MultiSpan::from_span(path_segment.ident.span); - sp.push_span_label( - path_segment.ident.span, - format!( - "this call modifies {} in-place", - match rcvr.kind { - ExprKind::Path(QPath::Resolved( - None, - hir::Path { segments: [segment], .. }, - )) => format!("`{}`", segment.ident), - _ => "its receiver".to_string(), - } - ), - ); + .type_dependent_def_id(expr.hir_id) + .map(|def_id| self.tcx.fn_sig(def_id).skip_binder().skip_binder()) + .and_then(|sig| sig.inputs_and_output.split_last()) + .map(|(output, inputs)| { + output.is_unit() + && inputs + .get(0) + .and_then(|self_ty| self_ty.ref_mutability()) + .map_or(false, rustc_ast::Mutability::is_mut) + }) + .unwrap_or(false) + }; + + if !(rcvr_has_the_expected_type || prev_call_mutates_and_returns_unit()) { + return; + } + + let mut sp = MultiSpan::from_span(path_segment.ident.span); + sp.push_span_label( + path_segment.ident.span, + format!( + "this call modifies {} in-place", + match rcvr.kind { + ExprKind::Path(QPath::Resolved( + None, + hir::Path { segments: [segment], .. }, + )) => format!("`{}`", segment.ident), + _ => "its receiver".to_string(), + } + ), + ); + + let modifies_rcvr_note = + format!("method `{}` modifies its receiver in-place", path_segment.ident); + if rcvr_has_the_expected_type { sp.push_span_label( rcvr.span, "you probably want to use this value after calling the method...", ); + err.span_note(sp, &modifies_rcvr_note); + err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident)); + } else if let ExprKind::MethodCall(..) = rcvr.kind { err.span_note( sp, - &format!("method `{}` modifies its receiver in-place", path_segment.ident), + modifies_rcvr_note.clone() + ", it is not meant to be used in method chains.", ); - err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident)); + } else { + err.span_note(sp, &modifies_rcvr_note); } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 7055d9257ec90..50f2b71250c01 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -416,6 +416,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); probe.is_ok() }); + + self.note_internal_mutation_in_method( + &mut err, + rcvr_expr, + expected.to_option(&self), + rcvr_ty, + ); } let mut custom_span_label = false; diff --git a/tests/ui/suggestions/chain-method-call-mutation-in-place.rs b/tests/ui/suggestions/chain-method-call-mutation-in-place.rs index cb92ab87a8ff7..7a4c747961c62 100644 --- a/tests/ui/suggestions/chain-method-call-mutation-in-place.rs +++ b/tests/ui/suggestions/chain-method-call-mutation-in-place.rs @@ -1,4 +1,8 @@ -fn main() {} +fn main() { + let x: Vec = vec![1, 2, 3].into_iter().collect::>().sort_by_key(|i| i); //~ ERROR mismatched types + vec![1, 2, 3].into_iter().collect::>().sort_by_key(|i| i).sort(); //~ ERROR no method named `sort` found for unit type `()` in the current scope +} + fn foo(mut s: String) -> String { s.push_str("asdf") //~ ERROR mismatched types } diff --git a/tests/ui/suggestions/chain-method-call-mutation-in-place.stderr b/tests/ui/suggestions/chain-method-call-mutation-in-place.stderr index 11d9b8391f6d2..128160f10adb3 100644 --- a/tests/ui/suggestions/chain-method-call-mutation-in-place.stderr +++ b/tests/ui/suggestions/chain-method-call-mutation-in-place.stderr @@ -1,5 +1,33 @@ error[E0308]: mismatched types - --> $DIR/chain-method-call-mutation-in-place.rs:3:5 + --> $DIR/chain-method-call-mutation-in-place.rs:2:23 + | +LL | let x: Vec = vec![1, 2, 3].into_iter().collect::>().sort_by_key(|i| i); + | -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Vec`, found `()` + | | + | expected due to this + | + = note: expected struct `Vec` + found unit type `()` +note: method `sort_by_key` modifies its receiver in-place, it is not meant to be used in method chains. + --> $DIR/chain-method-call-mutation-in-place.rs:2:71 + | +LL | let x: Vec = vec![1, 2, 3].into_iter().collect::>().sort_by_key(|i| i); + | ^^^^^^^^^^^ this call modifies its receiver in-place + +error[E0599]: no method named `sort` found for unit type `()` in the current scope + --> $DIR/chain-method-call-mutation-in-place.rs:3:72 + | +LL | vec![1, 2, 3].into_iter().collect::>().sort_by_key(|i| i).sort(); + | ^^^^ method not found in `()` + | +note: method `sort_by_key` modifies its receiver in-place, it is not meant to be used in method chains. + --> $DIR/chain-method-call-mutation-in-place.rs:3:53 + | +LL | vec![1, 2, 3].into_iter().collect::>().sort_by_key(|i| i).sort(); + | ^^^^^^^^^^^ this call modifies its receiver in-place + +error[E0308]: mismatched types + --> $DIR/chain-method-call-mutation-in-place.rs:7:5 | LL | fn foo(mut s: String) -> String { | ------ expected `String` because of return type @@ -7,7 +35,7 @@ LL | s.push_str("asdf") | ^^^^^^^^^^^^^^^^^^ expected `String`, found `()` | note: method `push_str` modifies its receiver in-place - --> $DIR/chain-method-call-mutation-in-place.rs:3:7 + --> $DIR/chain-method-call-mutation-in-place.rs:7:7 | LL | s.push_str("asdf") | - ^^^^^^^^ this call modifies `s` in-place @@ -15,6 +43,7 @@ LL | s.push_str("asdf") | you probably want to use this value after calling the method... = note: ...instead of the `()` output of method `push_str` -error: aborting due to previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0599. +For more information about an error, try `rustc --explain E0308`. From b36bbb0266a12f4869668f55aeaf4c8a68aa8265 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 14 Mar 2023 01:08:48 +0000 Subject: [PATCH 108/124] Don't codegen impossible to satisfy impls --- compiler/rustc_monomorphize/src/collector.rs | 15 +++++++++++++++ tests/ui/codegen/mono-impossible.rs | 13 +++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/ui/codegen/mono-impossible.rs diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index f529944acce63..aff27e5664b75 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1326,6 +1326,21 @@ fn create_mono_items_for_default_impls<'tcx>( return; } + // Unlike 'lazy' monomorphization that begins by collecting items transitively + // called by `main` or other global items, when eagerly monomorphizing impl + // items, we never actually check that the predicates of this impl are satisfied + // in a empty reveal-all param env (i.e. with no assumptions). + // + // Even though this impl has no substitutions, because we don't consider higher- + // ranked predicates such as `for<'a> &'a mut [u8]: Copy` to be trivially false, + // we must now check that the impl has no impossible-to-satisfy predicates. + if tcx.subst_and_check_impossible_predicates(( + item.owner_id.to_def_id(), + &InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id()), + )) { + return; + } + let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) else { return; }; diff --git a/tests/ui/codegen/mono-impossible.rs b/tests/ui/codegen/mono-impossible.rs new file mode 100644 index 0000000000000..1ea32ed2c4fac --- /dev/null +++ b/tests/ui/codegen/mono-impossible.rs @@ -0,0 +1,13 @@ +// compile-flags: -Clink-dead-code=on --crate-type=lib +// build-pass + +// Make sure that we don't monomorphize the impossible method `<() as Visit>::visit`, +// which does not hold under a reveal-all param env. + +pub trait Visit { + fn visit() {} +} + +pub trait Array<'a> {} + +impl Visit for () where (): for<'a> Array<'a> {} From ee2d42882f9d76b8fb54d749c35fec265026db47 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 14 Mar 2023 00:35:34 +0000 Subject: [PATCH 109/124] Use `unused_generic_params` from crate metadata --- .../rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 10 +++++++++- compiler/rustc_middle/src/query/keys.rs | 4 ++-- compiler/rustc_monomorphize/src/polymorphize.rs | 9 ++------- .../polymorphization/auxiliary/poly-dep.rs | 4 ++++ tests/codegen-units/polymorphization/poly-foreign.rs | 11 +++++++++++ 5 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 tests/codegen-units/polymorphization/auxiliary/poly-dep.rs create mode 100644 tests/codegen-units/polymorphization/poly-foreign.rs diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 83a0e833edc1d..2d8f2c8554f4b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -226,7 +226,15 @@ provide! { tcx, def_id, other, cdata, lookup_default_body_stability => { table } lookup_deprecation_entry => { table } params_in_repr => { table } - unused_generic_params => { table } + // FIXME: Could be defaulted, but `LazyValue` is not `FixedSizeEncoding`.. + unused_generic_params => { + cdata + .root + .tables + .unused_generic_params + .get(cdata, def_id.index) + .map_or_else(|| ty::UnusedGenericParams::new_all_used(), |lazy| lazy.decode((cdata, tcx))) + } opt_def_kind => { table_direct } impl_parent => { table } impl_polarity => { table_direct } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 78ee8a6a8fd64..6e961a775c1ff 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -63,7 +63,7 @@ impl<'tcx> Key for ty::InstanceDef<'tcx> { #[inline(always)] fn query_crate_is_local(&self) -> bool { - true + self.def_id().is_local() } fn default_span(&self, tcx: TyCtxt<'_>) -> Span { @@ -76,7 +76,7 @@ impl<'tcx> Key for ty::Instance<'tcx> { #[inline(always)] fn query_crate_is_local(&self) -> bool { - true + self.def_id().is_local() } fn default_span(&self, tcx: TyCtxt<'_>) -> Span { diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index b7c3dbcc09139..63263a642acc1 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -36,6 +36,8 @@ fn unused_generic_params<'tcx>( tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>, ) -> UnusedGenericParams { + assert!(instance.def_id().is_local()); + if !tcx.sess.opts.unstable_opts.polymorphize { // If polymorphization disabled, then all parameters are used. return UnusedGenericParams::new_all_used(); @@ -100,13 +102,6 @@ fn should_polymorphize<'tcx>( return false; } - // Polymorphization results are stored in cross-crate metadata only when there are unused - // parameters, so assume that non-local items must have only used parameters (else this query - // would not be invoked, and the cross-crate metadata used instead). - if !def_id.is_local() { - return false; - } - // Foreign items have no bodies to analyze. if tcx.is_foreign_item(def_id) { return false; diff --git a/tests/codegen-units/polymorphization/auxiliary/poly-dep.rs b/tests/codegen-units/polymorphization/auxiliary/poly-dep.rs new file mode 100644 index 0000000000000..fdbfa1b096d4b --- /dev/null +++ b/tests/codegen-units/polymorphization/auxiliary/poly-dep.rs @@ -0,0 +1,4 @@ +// compile-flags: -Zpolymorphize=on + +#[inline(never)] +pub fn foo() {} diff --git a/tests/codegen-units/polymorphization/poly-foreign.rs b/tests/codegen-units/polymorphization/poly-foreign.rs new file mode 100644 index 0000000000000..9da082daf114a --- /dev/null +++ b/tests/codegen-units/polymorphization/poly-foreign.rs @@ -0,0 +1,11 @@ +// aux-build:poly-dep.rs +// compile-flags: --crate-type=lib -Zprint-mono-items=eager -Zpolymorphize=on + +extern crate poly_dep; + +pub static FN1: fn() = poly_dep::foo::; +pub static FN2: fn() = poly_dep::foo::; + +//~ MONO_ITEM static FN1 +//~ MONO_ITEM static FN2 +//~ MONO_ITEM fn poly_dep::foo:: From 9eae77381ec58cd89346367fc498547c5e30c497 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 14 Mar 2023 18:43:37 +0000 Subject: [PATCH 110/124] Simplify proc macro signature validity check --- Cargo.lock | 1 + compiler/rustc_passes/Cargo.toml | 1 + compiler/rustc_passes/messages.ftl | 21 +-- compiler/rustc_passes/src/check_attr.rs | 146 +++++++----------- compiler/rustc_passes/src/errors.rs | 45 +----- tests/ui/proc-macro/bad-projection.rs | 15 ++ tests/ui/proc-macro/bad-projection.stderr | 9 ++ tests/ui/proc-macro/proc-macro-abi.rs | 6 +- tests/ui/proc-macro/proc-macro-abi.stderr | 21 ++- .../signature-proc-macro-attribute.rs | 10 +- .../signature-proc-macro-attribute.stderr | 46 +++--- .../proc-macro/signature-proc-macro-derive.rs | 9 +- .../signature-proc-macro-derive.stderr | 46 +++--- tests/ui/proc-macro/signature-proc-macro.rs | 9 +- .../ui/proc-macro/signature-proc-macro.stderr | 46 +++--- tests/ui/proc-macro/signature.rs | 6 +- tests/ui/proc-macro/signature.stderr | 35 +---- 17 files changed, 188 insertions(+), 284 deletions(-) create mode 100644 tests/ui/proc-macro/bad-projection.rs create mode 100644 tests/ui/proc-macro/bad-projection.stderr diff --git a/Cargo.lock b/Cargo.lock index 51332919fe755..243f4e6139c9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5139,6 +5139,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", + "rustc_trait_selection", "tracing", ] diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index faa9c493d8875..44f991f8c15b5 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -22,3 +22,4 @@ rustc_span = { path = "../rustc_span" } rustc_lexer = { path = "../rustc_lexer" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_feature = { path = "../rustc_feature" } +rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 3fa78efc290ba..d063b51c8b862 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -720,26 +720,7 @@ passes_ignored_derived_impls = *[other] traits {$trait_list}, but these are } intentionally ignored during dead code analysis -passes_proc_macro_typeerror = mismatched {$kind} signature - .label = found {$found}, expected type `proc_macro::TokenStream` - .note = {$kind}s must have a signature of `{$expected_signature}` - -passes_proc_macro_diff_arg_count = mismatched {$kind} signature - .label = found unexpected {$count -> - [one] argument - *[other] arguments - } - .note = {$kind}s must have a signature of `{$expected_signature}` - -passes_proc_macro_missing_args = mismatched {$kind} signature - .label = {$kind} must have {$expected_input_count -> - [one] one argument - *[other] two arguments - } of type `proc_macro::TokenStream` - -passes_proc_macro_invalid_abi = proc macro functions may not be `extern "{$abi}"` - -passes_proc_macro_unsafe = proc macro functions may not be `unsafe` +passes_proc_macro_bad_sig = {$kind} has incorrect signature passes_skipping_const_checks = skipping const checks diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c8d371dd0846b..0f92c5e74ae5d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -19,9 +19,10 @@ use rustc_hir::{ use rustc_hir::{MethodKind, Target, Unsafety}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; -use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; +use rustc_middle::traits::ObligationCause; +use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{ParamEnv, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::{ CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS, UNUSED_ATTRIBUTES, @@ -30,6 +31,9 @@ use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; +use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; +use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::traits::ObligationCtxt; use std::cell::Cell; use std::collections::hash_map::Entry; @@ -2188,100 +2192,66 @@ impl CheckAttrVisitor<'_> { /// /// If this best effort goes wrong, it will just emit a worse error later (see #102923) fn check_proc_macro(&self, hir_id: HirId, target: Target, kind: ProcMacroKind) { - let expected_input_count = match kind { - ProcMacroKind::Attribute => 2, - ProcMacroKind::Derive | ProcMacroKind::FunctionLike => 1, - }; - - let expected_signature = match kind { - ProcMacroKind::Attribute => "fn(TokenStream, TokenStream) -> TokenStream", - ProcMacroKind::Derive | ProcMacroKind::FunctionLike => "fn(TokenStream) -> TokenStream", - }; + if target != Target::Fn { + return; + } let tcx = self.tcx; - if target == Target::Fn { - let Some(tokenstream) = tcx.get_diagnostic_item(sym::TokenStream) else {return}; - let tokenstream = tcx.type_of(tokenstream).subst_identity(); - - let id = hir_id.expect_owner(); - let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id).unwrap(); - - let sig = - tcx.liberate_late_bound_regions(id.to_def_id(), tcx.fn_sig(id).subst_identity()); - let sig = tcx.normalize_erasing_regions(ParamEnv::empty(), sig); - - // We don't currently require that the function signature is equal to - // `fn(TokenStream) -> TokenStream`, but instead monomorphizes to - // `fn(TokenStream) -> TokenStream` after some substitution of generic arguments. - // - // Properly checking this means pulling in additional `rustc` crates, so we don't. - let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::AsCandidateKey }; - - if sig.abi != Abi::Rust { - tcx.sess.emit_err(errors::ProcMacroInvalidAbi { - span: hir_sig.span, - abi: sig.abi.name(), - }); - self.abort.set(true); - } + let Some(token_stream_def_id) = tcx.get_diagnostic_item(sym::TokenStream) else { return; }; + let Some(token_stream) = tcx.type_of(token_stream_def_id).no_bound_vars() else { return; }; - if sig.unsafety == Unsafety::Unsafe { - tcx.sess.emit_err(errors::ProcMacroUnsafe { span: hir_sig.span }); - self.abort.set(true); - } + let def_id = hir_id.expect_owner().def_id; + let param_env = ty::ParamEnv::empty(); - let output = sig.output(); + let infcx = tcx.infer_ctxt().build(); + let ocx = ObligationCtxt::new(&infcx); - // Typecheck the output - if !drcx.types_may_unify(output, tokenstream) { - tcx.sess.emit_err(errors::ProcMacroTypeError { - span: hir_sig.decl.output.span(), - found: output, - kind, - expected_signature, - }); - self.abort.set(true); - } + let span = tcx.def_span(def_id); + let fresh_substs = infcx.fresh_substs_for_item(span, def_id.to_def_id()); + let sig = tcx.liberate_late_bound_regions( + def_id.to_def_id(), + tcx.fn_sig(def_id).subst(tcx, fresh_substs), + ); - if sig.inputs().len() < expected_input_count { - tcx.sess.emit_err(errors::ProcMacroMissingArguments { - expected_input_count, - span: hir_sig.span, - kind, - expected_signature, - }); - self.abort.set(true); - } + let cause = ObligationCause::misc(span, def_id); + let sig = ocx.normalize(&cause, param_env, sig); - // Check that the inputs are correct, if there are enough. - if sig.inputs().len() >= expected_input_count { - for (arg, input) in - sig.inputs().iter().zip(hir_sig.decl.inputs).take(expected_input_count) - { - if !drcx.types_may_unify(*arg, tokenstream) { - tcx.sess.emit_err(errors::ProcMacroTypeError { - span: input.span, - found: *arg, - kind, - expected_signature, - }); - self.abort.set(true); - } - } - } + // proc macro is not WF. + let errors = ocx.select_where_possible(); + if !errors.is_empty() { + return; + } - // Check that there are not too many arguments - let body_id = tcx.hir().body_owned_by(id.def_id); - let excess = tcx.hir().body(body_id).params.get(expected_input_count..); - if let Some(excess @ [begin @ end] | excess @ [begin, .., end]) = excess { - tcx.sess.emit_err(errors::ProcMacroDiffArguments { - span: begin.span.to(end.span), - count: excess.len(), - kind, - expected_signature, - }); - self.abort.set(true); - } + let expected_sig = tcx.mk_fn_sig( + std::iter::repeat(token_stream).take(match kind { + ProcMacroKind::Attribute => 2, + ProcMacroKind::Derive | ProcMacroKind::FunctionLike => 1, + }), + token_stream, + false, + Unsafety::Normal, + Abi::Rust, + ); + + if let Err(terr) = ocx.eq(&cause, param_env, expected_sig, sig) { + let mut diag = tcx.sess.create_err(errors::ProcMacroBadSig { span, kind }); + infcx.err_ctxt().note_type_err( + &mut diag, + &cause, + None, + Some(ValuePairs::Sigs(ExpectedFound { expected: expected_sig, found: sig })), + terr, + false, + false, + ); + diag.emit(); + self.abort.set(true); + } + + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + infcx.err_ctxt().report_fulfillment_errors(&errors); + self.abort.set(true); } } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 9f1c0b5a0b7bd..1b0cd5d91ab53 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1546,52 +1546,11 @@ pub struct ChangeFieldsToBeOfUnitType { } #[derive(Diagnostic)] -#[diag(passes_proc_macro_typeerror)] -#[note] -pub(crate) struct ProcMacroTypeError<'tcx> { - #[primary_span] - #[label] - pub span: Span, - pub found: Ty<'tcx>, - pub kind: ProcMacroKind, - pub expected_signature: &'static str, -} - -#[derive(Diagnostic)] -#[diag(passes_proc_macro_diff_arg_count)] -pub(crate) struct ProcMacroDiffArguments { - #[primary_span] - #[label] - pub span: Span, - pub count: usize, - pub kind: ProcMacroKind, - pub expected_signature: &'static str, -} - -#[derive(Diagnostic)] -#[diag(passes_proc_macro_missing_args)] -pub(crate) struct ProcMacroMissingArguments { +#[diag(passes_proc_macro_bad_sig)] +pub(crate) struct ProcMacroBadSig { #[primary_span] - #[label] pub span: Span, - pub expected_input_count: usize, pub kind: ProcMacroKind, - pub expected_signature: &'static str, -} - -#[derive(Diagnostic)] -#[diag(passes_proc_macro_invalid_abi)] -pub(crate) struct ProcMacroInvalidAbi { - #[primary_span] - pub span: Span, - pub abi: &'static str, -} - -#[derive(Diagnostic)] -#[diag(passes_proc_macro_unsafe)] -pub(crate) struct ProcMacroUnsafe { - #[primary_span] - pub span: Span, } #[derive(Diagnostic)] diff --git a/tests/ui/proc-macro/bad-projection.rs b/tests/ui/proc-macro/bad-projection.rs new file mode 100644 index 0000000000000..d214c7ac8b274 --- /dev/null +++ b/tests/ui/proc-macro/bad-projection.rs @@ -0,0 +1,15 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![allow(warnings)] + +extern crate proc_macro; + +trait Project { + type Assoc; +} + +#[proc_macro] +pub fn uwu() -> <() as Project>::Assoc {} +//~^ ERROR the trait bound `(): Project` is not satisfied diff --git a/tests/ui/proc-macro/bad-projection.stderr b/tests/ui/proc-macro/bad-projection.stderr new file mode 100644 index 0000000000000..8a8246376fe08 --- /dev/null +++ b/tests/ui/proc-macro/bad-projection.stderr @@ -0,0 +1,9 @@ +error[E0277]: the trait bound `(): Project` is not satisfied + --> $DIR/bad-projection.rs:14:17 + | +LL | pub fn uwu() -> <() as Project>::Assoc {} + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Project` is not implemented for `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/proc-macro/proc-macro-abi.rs b/tests/ui/proc-macro/proc-macro-abi.rs index 873660a5b3ab9..93a613e8b8fc3 100644 --- a/tests/ui/proc-macro/proc-macro-abi.rs +++ b/tests/ui/proc-macro/proc-macro-abi.rs @@ -9,19 +9,19 @@ use proc_macro::TokenStream; #[proc_macro] pub extern "C" fn abi(a: TokenStream) -> TokenStream { - //~^ ERROR proc macro functions may not be `extern "C"` + //~^ ERROR function-like proc macro has incorrect signature a } #[proc_macro] pub extern "system" fn abi2(a: TokenStream) -> TokenStream { - //~^ ERROR proc macro functions may not be `extern "system"` + //~^ ERROR function-like proc macro has incorrect signature a } #[proc_macro] pub extern fn abi3(a: TokenStream) -> TokenStream { - //~^ ERROR proc macro functions may not be `extern "C"` + //~^ ERROR function-like proc macro has incorrect signature a } diff --git a/tests/ui/proc-macro/proc-macro-abi.stderr b/tests/ui/proc-macro/proc-macro-abi.stderr index 9a781be0996dd..ccc72e5187ed3 100644 --- a/tests/ui/proc-macro/proc-macro-abi.stderr +++ b/tests/ui/proc-macro/proc-macro-abi.stderr @@ -1,20 +1,29 @@ -error: proc macro functions may not be `extern "C"` +error: function-like proc macro has incorrect signature --> $DIR/proc-macro-abi.rs:11:1 | LL | pub extern "C" fn abi(a: TokenStream) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "C" fn + | + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `extern "C" fn(proc_macro::TokenStream) -> proc_macro::TokenStream` -error: proc macro functions may not be `extern "system"` +error: function-like proc macro has incorrect signature --> $DIR/proc-macro-abi.rs:17:1 | LL | pub extern "system" fn abi2(a: TokenStream) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "system" fn + | + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `extern "system" fn(proc_macro::TokenStream) -> proc_macro::TokenStream` -error: proc macro functions may not be `extern "C"` +error: function-like proc macro has incorrect signature --> $DIR/proc-macro-abi.rs:23:1 | LL | pub extern fn abi3(a: TokenStream) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "C" fn + | + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `extern "C" fn(proc_macro::TokenStream) -> proc_macro::TokenStream` error: aborting due to 3 previous errors diff --git a/tests/ui/proc-macro/signature-proc-macro-attribute.rs b/tests/ui/proc-macro/signature-proc-macro-attribute.rs index 51abc8e7d3edb..fb48f748ce004 100644 --- a/tests/ui/proc-macro/signature-proc-macro-attribute.rs +++ b/tests/ui/proc-macro/signature-proc-macro-attribute.rs @@ -8,25 +8,23 @@ use proc_macro::TokenStream; #[proc_macro_attribute] pub fn bad_input(input: String) -> TokenStream { - //~^ ERROR mismatched attribute proc macro signature + //~^ ERROR attribute proc macro has incorrect signature ::proc_macro::TokenStream::new() } #[proc_macro_attribute] pub fn bad_output(input: TokenStream) -> String { - //~^ ERROR mismatched attribute proc macro signature - //~| ERROR mismatched attribute proc macro signature + //~^ ERROR attribute proc macro has incorrect signature String::from("blah") } #[proc_macro_attribute] pub fn bad_everything(input: String) -> String { - //~^ ERROR mismatched attribute proc macro signature - //~| ERROR mismatched attribute proc macro signature + //~^ ERROR attribute proc macro has incorrect signature input } #[proc_macro_attribute] pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { - //~^ ERROR mismatched attribute proc macro signature + //~^ ERROR attribute proc macro has incorrect signature } diff --git a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr index abf7a6f3ce922..afbd18a4f7858 100644 --- a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr @@ -1,42 +1,38 @@ -error: mismatched attribute proc macro signature +error: attribute proc macro has incorrect signature --> $DIR/signature-proc-macro-attribute.rs:10:1 | LL | pub fn bad_input(input: String) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attribute proc macro must have two arguments of type `proc_macro::TokenStream` - -error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:16:42 - | -LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters | - = note: attribute proc macros must have a signature of `fn(TokenStream, TokenStream) -> TokenStream` + = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(std::string::String) -> proc_macro::TokenStream` -error: mismatched attribute proc macro signature +error: attribute proc macro has incorrect signature --> $DIR/signature-proc-macro-attribute.rs:16:1 | LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attribute proc macro must have two arguments of type `proc_macro::TokenStream` - -error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:23:41 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters | -LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` - | - = note: attribute proc macros must have a signature of `fn(TokenStream, TokenStream) -> TokenStream` + = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(proc_macro::TokenStream) -> std::string::String` -error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:23:1 +error: attribute proc macro has incorrect signature + --> $DIR/signature-proc-macro-attribute.rs:22:1 | LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attribute proc macro must have two arguments of type `proc_macro::TokenStream` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters + | + = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(std::string::String) -> std::string::String` -error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:30:49 +error: attribute proc macro has incorrect signature + --> $DIR/signature-proc-macro-attribute.rs:28:1 | LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { - | ^^^^^^^^^ found unexpected argument + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters + | + = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/signature-proc-macro-derive.rs b/tests/ui/proc-macro/signature-proc-macro-derive.rs index f2fd824b675b6..d294b15912794 100644 --- a/tests/ui/proc-macro/signature-proc-macro-derive.rs +++ b/tests/ui/proc-macro/signature-proc-macro-derive.rs @@ -8,24 +8,23 @@ use proc_macro::TokenStream; #[proc_macro_derive(Blah)] pub fn bad_input(input: String) -> TokenStream { - //~^ ERROR mismatched derive proc macro signature + //~^ ERROR derive proc macro has incorrect signature TokenStream::new() } #[proc_macro_derive(Bleh)] pub fn bad_output(input: TokenStream) -> String { - //~^ ERROR mismatched derive proc macro signature + //~^ ERROR derive proc macro has incorrect signature String::from("blah") } #[proc_macro_derive(Bluh)] pub fn bad_everything(input: String) -> String { - //~^ ERROR mismatched derive proc macro signature - //~| ERROR mismatched derive proc macro signature + //~^ ERROR derive proc macro has incorrect signature input } #[proc_macro_derive(Blih)] pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { - //~^ ERROR mismatched derive proc macro signature + //~^ ERROR derive proc macro has incorrect signature } diff --git a/tests/ui/proc-macro/signature-proc-macro-derive.stderr b/tests/ui/proc-macro/signature-proc-macro-derive.stderr index a358ae277037f..7a75a808e1959 100644 --- a/tests/ui/proc-macro/signature-proc-macro-derive.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-derive.stderr @@ -1,40 +1,38 @@ -error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:10:25 +error: derive proc macro has incorrect signature + --> $DIR/signature-proc-macro-derive.rs:10:1 | LL | pub fn bad_input(input: String) -> TokenStream { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | - = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(std::string::String) -> proc_macro::TokenStream` -error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:16:42 +error: derive proc macro has incorrect signature + --> $DIR/signature-proc-macro-derive.rs:16:1 | LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | - = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(proc_macro::TokenStream) -> std::string::String` -error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:22:41 +error: derive proc macro has incorrect signature + --> $DIR/signature-proc-macro-derive.rs:22:1 | LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | - = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(std::string::String) -> std::string::String` -error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:22:30 - | -LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` - | - = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` - -error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:29:33 +error: derive proc macro has incorrect signature + --> $DIR/signature-proc-macro-derive.rs:28:1 | LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ found unexpected arguments + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters + | + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/signature-proc-macro.rs b/tests/ui/proc-macro/signature-proc-macro.rs index 54770aacd1a98..ca2509ed84b5d 100644 --- a/tests/ui/proc-macro/signature-proc-macro.rs +++ b/tests/ui/proc-macro/signature-proc-macro.rs @@ -8,24 +8,23 @@ use proc_macro::TokenStream; #[proc_macro] pub fn bad_input(input: String) -> TokenStream { - //~^ ERROR mismatched function-like proc macro signature + //~^ ERROR function-like proc macro has incorrect signature ::proc_macro::TokenStream::new() } #[proc_macro] pub fn bad_output(input: TokenStream) -> String { - //~^ ERROR mismatched function-like proc macro signature + //~^ ERROR function-like proc macro has incorrect signature String::from("blah") } #[proc_macro] pub fn bad_everything(input: String) -> String { - //~^ ERROR mismatched function-like proc macro signature - //~| ERROR mismatched function-like proc macro signature + //~^ ERROR function-like proc macro has incorrect signature input } #[proc_macro] pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { - //~^ ERROR mismatched function-like proc macro signature + //~^ ERROR function-like proc macro has incorrect signature } diff --git a/tests/ui/proc-macro/signature-proc-macro.stderr b/tests/ui/proc-macro/signature-proc-macro.stderr index 4b14a54e67503..3a4bd7301305c 100644 --- a/tests/ui/proc-macro/signature-proc-macro.stderr +++ b/tests/ui/proc-macro/signature-proc-macro.stderr @@ -1,40 +1,38 @@ -error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:10:25 +error: function-like proc macro has incorrect signature + --> $DIR/signature-proc-macro.rs:10:1 | LL | pub fn bad_input(input: String) -> TokenStream { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | - = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(std::string::String) -> proc_macro::TokenStream` -error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:16:42 +error: function-like proc macro has incorrect signature + --> $DIR/signature-proc-macro.rs:16:1 | LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | - = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(proc_macro::TokenStream) -> std::string::String` -error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:22:41 +error: function-like proc macro has incorrect signature + --> $DIR/signature-proc-macro.rs:22:1 | LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | - = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(std::string::String) -> std::string::String` -error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:22:30 - | -LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` - | - = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` - -error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:29:33 +error: function-like proc macro has incorrect signature + --> $DIR/signature-proc-macro.rs:28:1 | LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ found unexpected arguments + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters + | + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/signature.rs b/tests/ui/proc-macro/signature.rs index 11187aa31bd80..7b4982a6178f9 100644 --- a/tests/ui/proc-macro/signature.rs +++ b/tests/ui/proc-macro/signature.rs @@ -8,10 +8,6 @@ extern crate proc_macro; #[proc_macro_derive(A)] pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { - //~^ ERROR: mismatched derive proc macro signature - //~| mismatched derive proc macro signature - //~| mismatched derive proc macro signature - //~| proc macro functions may not be `extern - //~| proc macro functions may not be `unsafe + //~^ ERROR: derive proc macro has incorrect signature loop {} } diff --git a/tests/ui/proc-macro/signature.stderr b/tests/ui/proc-macro/signature.stderr index 3dbe3f22a0df8..ba5c8c1571e58 100644 --- a/tests/ui/proc-macro/signature.stderr +++ b/tests/ui/proc-macro/signature.stderr @@ -1,36 +1,11 @@ -error: proc macro functions may not be `extern "C"` +error: derive proc macro has incorrect signature --> $DIR/signature.rs:10:1 | LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: proc macro functions may not be `unsafe` - --> $DIR/signature.rs:10:1 - | -LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: mismatched derive proc macro signature - --> $DIR/signature.rs:10:49 - | -LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { - | ^^^ found u32, expected type `proc_macro::TokenStream` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected normal fn, found unsafe fn | - = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` - -error: mismatched derive proc macro signature - --> $DIR/signature.rs:10:33 - | -LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { - | ^^^ found i32, expected type `proc_macro::TokenStream` - | - = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` - -error: mismatched derive proc macro signature - --> $DIR/signature.rs:10:38 - | -LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { - | ^^^^^^ found unexpected argument + = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + found signature `unsafe extern "C" fn(i32, u32) -> u32` -error: aborting due to 5 previous errors +error: aborting due to previous error From 00dc3b24b7cf3db69ce4b3648e1fb9d1cd539c67 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 14 Mar 2023 19:05:15 +0000 Subject: [PATCH 111/124] Tighter spans --- compiler/rustc_passes/src/check_attr.rs | 37 ++++++++++++++++++- .../signature-proc-macro-attribute.stderr | 4 +- .../signature-proc-macro-derive.stderr | 16 ++++---- .../ui/proc-macro/signature-proc-macro.stderr | 16 ++++---- 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0f92c5e74ae5d..8bed788814209 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -20,7 +20,7 @@ use rustc_hir::{MethodKind, Target, Unsafety}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::error::ExpectedFound; +use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::{ @@ -2213,7 +2213,7 @@ impl CheckAttrVisitor<'_> { tcx.fn_sig(def_id).subst(tcx, fresh_substs), ); - let cause = ObligationCause::misc(span, def_id); + let mut cause = ObligationCause::misc(span, def_id); let sig = ocx.normalize(&cause, param_env, sig); // proc macro is not WF. @@ -2235,6 +2235,39 @@ impl CheckAttrVisitor<'_> { if let Err(terr) = ocx.eq(&cause, param_env, expected_sig, sig) { let mut diag = tcx.sess.create_err(errors::ProcMacroBadSig { span, kind }); + + let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id); + if let Some(hir_sig) = hir_sig { + match terr { + TypeError::ArgumentMutability(idx) | TypeError::ArgumentSorts(_, idx) => { + if let Some(ty) = hir_sig.decl.inputs.get(idx) { + diag.set_span(ty.span); + cause.span = ty.span; + } else if idx == hir_sig.decl.inputs.len() { + let span = hir_sig.decl.output.span(); + diag.set_span(span); + cause.span = span; + } + } + TypeError::ArgCount => { + if let Some(ty) = hir_sig.decl.inputs.get(expected_sig.inputs().len()) { + diag.set_span(ty.span); + cause.span = ty.span; + } + } + TypeError::UnsafetyMismatch(_) => { + // FIXME: Would be nice if we had a span here.. + } + TypeError::AbiMismatch(_) => { + // FIXME: Would be nice if we had a span here.. + } + TypeError::VariadicMismatch(_) => { + // FIXME: Would be nice if we had a span here.. + } + _ => {} + } + } + infcx.err_ctxt().note_type_err( &mut diag, &cause, diff --git a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr index afbd18a4f7858..ce832eaa5c7af 100644 --- a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr @@ -26,10 +26,10 @@ LL | pub fn bad_everything(input: String) -> String { found signature `fn(std::string::String) -> std::string::String` error: attribute proc macro has incorrect signature - --> $DIR/signature-proc-macro-attribute.rs:28:1 + --> $DIR/signature-proc-macro-attribute.rs:28:52 | LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters + | ^^^^^^ incorrect number of function parameters | = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` diff --git a/tests/ui/proc-macro/signature-proc-macro-derive.stderr b/tests/ui/proc-macro/signature-proc-macro-derive.stderr index 7a75a808e1959..03c6abad17d91 100644 --- a/tests/ui/proc-macro/signature-proc-macro-derive.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-derive.stderr @@ -1,35 +1,35 @@ error: derive proc macro has incorrect signature - --> $DIR/signature-proc-macro-derive.rs:10:1 + --> $DIR/signature-proc-macro-derive.rs:10:25 | LL | pub fn bad_input(input: String) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` found signature `fn(std::string::String) -> proc_macro::TokenStream` error: derive proc macro has incorrect signature - --> $DIR/signature-proc-macro-derive.rs:16:1 + --> $DIR/signature-proc-macro-derive.rs:16:42 | LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` found signature `fn(proc_macro::TokenStream) -> std::string::String` error: derive proc macro has incorrect signature - --> $DIR/signature-proc-macro-derive.rs:22:1 + --> $DIR/signature-proc-macro-derive.rs:22:30 | LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` found signature `fn(std::string::String) -> std::string::String` error: derive proc macro has incorrect signature - --> $DIR/signature-proc-macro-derive.rs:28:1 + --> $DIR/signature-proc-macro-derive.rs:28:36 | LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters + | ^^^^^^^^^^^ incorrect number of function parameters | = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` diff --git a/tests/ui/proc-macro/signature-proc-macro.stderr b/tests/ui/proc-macro/signature-proc-macro.stderr index 3a4bd7301305c..dd2cb0570daa2 100644 --- a/tests/ui/proc-macro/signature-proc-macro.stderr +++ b/tests/ui/proc-macro/signature-proc-macro.stderr @@ -1,35 +1,35 @@ error: function-like proc macro has incorrect signature - --> $DIR/signature-proc-macro.rs:10:1 + --> $DIR/signature-proc-macro.rs:10:25 | LL | pub fn bad_input(input: String) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` found signature `fn(std::string::String) -> proc_macro::TokenStream` error: function-like proc macro has incorrect signature - --> $DIR/signature-proc-macro.rs:16:1 + --> $DIR/signature-proc-macro.rs:16:42 | LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` found signature `fn(proc_macro::TokenStream) -> std::string::String` error: function-like proc macro has incorrect signature - --> $DIR/signature-proc-macro.rs:22:1 + --> $DIR/signature-proc-macro.rs:22:30 | LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` | = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` found signature `fn(std::string::String) -> std::string::String` error: function-like proc macro has incorrect signature - --> $DIR/signature-proc-macro.rs:28:1 + --> $DIR/signature-proc-macro.rs:28:36 | LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters + | ^^^^^^^^^^^ incorrect number of function parameters | = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` From c49658a815e98e7c7afce80166bf1f83258ca84f Mon Sep 17 00:00:00 2001 From: Robin Hafid Date: Tue, 14 Mar 2023 14:19:33 -0500 Subject: [PATCH 112/124] Rename 'src/bootstrap/native.rs' to llvm.rs Renamed 'native.rs' to 'llvm.rs', also moved `TestHelpers` to `test.rs`.Replaced all the `native.rs` ocurrences at `src/bootstrap` files to `llvm.rs` --- src/bootstrap/builder.rs | 14 ++--- src/bootstrap/compile.rs | 18 +++---- src/bootstrap/config.rs | 6 +-- src/bootstrap/config/tests.rs | 2 +- src/bootstrap/dist.rs | 12 ++--- src/bootstrap/download.rs | 2 +- src/bootstrap/lib.rs | 2 +- src/bootstrap/{native.rs => llvm.rs} | 65 ----------------------- src/bootstrap/test.rs | 79 +++++++++++++++++++++++++--- src/ci/stage-build.py | 2 +- 10 files changed, 101 insertions(+), 101 deletions(-) rename src/bootstrap/{native.rs => llvm.rs} (95%) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index bb07ca1908e1c..72d6713ccb3a4 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -16,7 +16,7 @@ use crate::config::{SplitDebuginfo, TargetSelection}; use crate::doc; use crate::flags::{Color, Subcommand}; use crate::install; -use crate::native; +use crate::llvm; use crate::run; use crate::setup; use crate::test; @@ -636,13 +636,13 @@ impl<'a> Builder<'a> { tool::Rustdoc, tool::Clippy, tool::CargoClippy, - native::Llvm, - native::Sanitizers, + llvm::Llvm, + llvm::Sanitizers, tool::Rustfmt, tool::Miri, tool::CargoMiri, - native::Lld, - native::CrtBeginEnd + llvm::Lld, + llvm::CrtBeginEnd ), Kind::Check | Kind::Clippy | Kind::Fix => describe!( check::Std, @@ -1101,7 +1101,7 @@ impl<'a> Builder<'a> { /// check build or dry-run, where there's no need to build all of LLVM. fn llvm_config(&self, target: TargetSelection) -> Option { if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run() { - let native::LlvmResult { llvm_config, .. } = self.ensure(native::Llvm { target }); + let llvm::LlvmResult { llvm_config, .. } = self.ensure(llvm::Llvm { target }); if llvm_config.is_file() { return Some(llvm_config); } @@ -1227,7 +1227,7 @@ impl<'a> Builder<'a> { // rustc_llvm. But if LLVM is stale, that'll be a tiny amount // of work comparatively, and we'd likely need to rebuild it anyway, // so that's okay. - if crate::native::prebuilt_llvm_config(self, target).is_err() { + if crate::llvm::prebuilt_llvm_config(self, target).is_err() { cargo.env("RUST_CHECK", "1"); } } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8b80dfc0f9b97..74aadbb5b5d23 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -24,7 +24,7 @@ use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::config::{LlvmLibunwind, RustcLto, TargetSelection}; use crate::dist; -use crate::native; +use crate::llvm; use crate::tool::SourceType; use crate::util::get_clang_cl_resource_dir; use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date}; @@ -191,7 +191,7 @@ fn copy_and_stamp( } fn copy_llvm_libunwind(builder: &Builder<'_>, target: TargetSelection, libdir: &Path) -> PathBuf { - let libunwind_path = builder.ensure(native::Libunwind { target }); + let libunwind_path = builder.ensure(llvm::Libunwind { target }); let libunwind_source = libunwind_path.join("libunwind.a"); let libunwind_target = libdir.join("libunwind.a"); builder.copy(&libunwind_source, &libunwind_target); @@ -266,7 +266,7 @@ fn copy_self_contained_objects( DependencyType::TargetSelfContained, ); } - let crt_path = builder.ensure(native::CrtBeginEnd { target }); + let crt_path = builder.ensure(llvm::CrtBeginEnd { target }); for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { let src = crt_path.join(obj); let target = libdir_self_contained.join(obj); @@ -468,7 +468,7 @@ fn copy_sanitizers( compiler: &Compiler, target: TargetSelection, ) -> Vec { - let runtimes: Vec = builder.ensure(native::Sanitizers { target }); + let runtimes: Vec = builder.ensure(llvm::Sanitizers { target }); if builder.config.dry_run() { return Vec::new(); @@ -870,12 +870,12 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS // busting caches (e.g. like #71152). if builder.config.llvm_enabled() && (builder.kind != Kind::Check - || crate::native::prebuilt_llvm_config(builder, target).is_ok()) + || crate::llvm::prebuilt_llvm_config(builder, target).is_ok()) { if builder.is_rust_llvm(target) { cargo.env("LLVM_RUSTLLVM", "1"); } - let native::LlvmResult { llvm_config, .. } = builder.ensure(native::Llvm { target }); + let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target }); cargo.env("LLVM_CONFIG", &llvm_config); if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { cargo.env("CFG_LLVM_ROOT", s); @@ -1353,7 +1353,7 @@ impl Step for Assemble { } let lld_install = if builder.config.lld_enabled { - Some(builder.ensure(native::Lld { target: target_compiler.host })) + Some(builder.ensure(llvm::Lld { target: target_compiler.host })) } else { None }; @@ -1417,8 +1417,8 @@ impl Step for Assemble { } if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) { - let native::LlvmResult { llvm_config, .. } = - builder.ensure(native::Llvm { target: target_compiler.host }); + let llvm::LlvmResult { llvm_config, .. } = + builder.ensure(llvm::Llvm { target: target_compiler.host }); if !builder.config.dry_run() { let llvm_bin_dir = output(Command::new(llvm_config).arg("--bindir")); let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index fc5aa8a245d2d..5b9bf0adb63b2 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -1190,11 +1190,11 @@ impl Config { 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, asserts) + crate::llvm::is_ci_llvm_available(&config, asserts) } Some(StringOrBool::Bool(b)) => b, None => { - config.channel == "dev" && crate::native::is_ci_llvm_available(&config, asserts) + config.channel == "dev" && crate::llvm::is_ci_llvm_available(&config, asserts) } }; @@ -1237,7 +1237,7 @@ impl Config { } } else { config.llvm_from_ci = - config.channel == "dev" && crate::native::is_ci_llvm_available(&config, false); + config.channel == "dev" && crate::llvm::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 index 16dc8c63abc96..5cea143e0a787 100644 --- a/src/bootstrap/config/tests.rs +++ b/src/bootstrap/config/tests.rs @@ -11,7 +11,7 @@ fn parse(config: &str) -> Config { #[test] fn download_ci_llvm() { - if crate::native::is_ci_llvm_modified(&parse("")) { + if crate::llvm::is_ci_llvm_modified(&parse("")) { eprintln!("Detected LLVM as non-available: running in CI and modified LLVM in this change"); return; } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index a3d9cb3e10c21..9f8584d4c2df6 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -27,7 +27,7 @@ use crate::channel; use crate::compile; use crate::config::TargetSelection; use crate::doc::DocumentationFormat; -use crate::native; +use crate::llvm; use crate::tarball::{GeneratedTarball, OverlayKind, Tarball}; use crate::tool::{self, Tool}; use crate::util::{exe, is_dylib, output, t, timeit}; @@ -1961,8 +1961,8 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir builder.install(&llvm_dylib_path, dst_libdir, 0o644); } !builder.config.dry_run() - } else if let Ok(native::LlvmResult { llvm_config, .. }) = - native::prebuilt_llvm_config(builder, target) + } else if let Ok(llvm::LlvmResult { llvm_config, .. }) = + llvm::prebuilt_llvm_config(builder, target) { let mut cmd = Command::new(llvm_config); cmd.arg("--libfiles"); @@ -2150,7 +2150,7 @@ impl Step for LlvmTools { } } - builder.ensure(crate::native::Llvm { target }); + builder.ensure(crate::llvm::Llvm { target }); let mut tarball = Tarball::new(builder, "llvm-tools", &target.triple); tarball.set_overlay(OverlayKind::LLVM); @@ -2209,10 +2209,10 @@ impl Step for RustDev { let mut tarball = Tarball::new(builder, "rust-dev", &target.triple); tarball.set_overlay(OverlayKind::LLVM); - builder.ensure(crate::native::Llvm { target }); + builder.ensure(crate::llvm::Llvm { target }); // We want to package `lld` to use it with `download-ci-llvm`. - builder.ensure(crate::native::Lld { target }); + builder.ensure(crate::llvm::Lld { target }); let src_bindir = builder.llvm_out(target).join("bin"); // If updating this list, you likely want to change diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index d1e2149d3f95f..8fbc034965a6c 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -12,7 +12,7 @@ use xz2::bufread::XzDecoder; use crate::{ config::RustfmtMetadata, - native::detect_llvm_sha, + llvm::detect_llvm_sha, t, util::{check_run, exe, program_out_of_date, try_run}, Config, diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 22ddf87221595..84d3a712b7fd1 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -53,8 +53,8 @@ mod download; mod flags; mod format; mod install; +mod llvm; mod metadata; -mod native; mod run; mod sanity; mod setup; diff --git a/src/bootstrap/native.rs b/src/bootstrap/llvm.rs similarity index 95% rename from src/bootstrap/native.rs rename to src/bootstrap/llvm.rs index 040e36ea5f8d8..9c5524a863261 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/llvm.rs @@ -869,71 +869,6 @@ impl Step for Lld { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct TestHelpers { - pub target: TargetSelection, -} - -impl Step for TestHelpers { - type Output = (); - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("tests/auxiliary/rust_test_helpers.c") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(TestHelpers { target: run.target }) - } - - /// Compiles the `rust_test_helpers.c` library which we used in various - /// `run-pass` tests for ABI testing. - fn run(self, builder: &Builder<'_>) { - if builder.config.dry_run() { - return; - } - // The x86_64-fortanix-unknown-sgx target doesn't have a working C - // toolchain. However, some x86_64 ELF objects can be linked - // without issues. Use this hack to compile the test helpers. - let target = if self.target == "x86_64-fortanix-unknown-sgx" { - TargetSelection::from_user("x86_64-unknown-linux-gnu") - } else { - self.target - }; - let dst = builder.test_helpers_out(target); - let src = builder.src.join("tests/auxiliary/rust_test_helpers.c"); - if up_to_date(&src, &dst.join("librust_test_helpers.a")) { - return; - } - - builder.info("Building test helpers"); - t!(fs::create_dir_all(&dst)); - let mut cfg = cc::Build::new(); - // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 - if target.contains("emscripten") { - cfg.pic(false); - } - - // We may have found various cross-compilers a little differently due to our - // extra configuration, so inform cc of these compilers. Note, though, that - // on MSVC we still need cc's detection of env vars (ugh). - if !target.contains("msvc") { - if let Some(ar) = builder.ar(target) { - cfg.archiver(ar); - } - cfg.compiler(builder.cc(target)); - } - cfg.cargo_metadata(false) - .out_dir(&dst) - .target(&target.triple) - .host(&builder.config.build.triple) - .opt_level(0) - .warnings(false) - .debug(false) - .file(builder.src.join("tests/auxiliary/rust_test_helpers.c")) - .compile("rust_test_helpers"); - } -} - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Sanitizers { pub target: TargetSelection, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f5d680df1133b..b7dbb8444fd00 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -19,10 +19,10 @@ use crate::config::TargetSelection; use crate::dist; use crate::doc::DocumentationFormat; use crate::flags::Subcommand; -use crate::native; +use crate::llvm; use crate::tool::{self, SourceType, Tool}; use crate::toolstate::ToolState; -use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t}; +use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t, up_to_date}; use crate::{envify, CLang, DocTests, GitRepo, Mode}; const ADB_TEST_DIR: &str = "/data/local/tmp/work"; @@ -1430,11 +1430,11 @@ note: if you're sure you want to do this, please open an issue as to why. In the builder.ensure(compile::Std::new(compiler, compiler.host)); // Also provide `rust_test_helpers` for the host. - builder.ensure(native::TestHelpers { target: compiler.host }); + builder.ensure(TestHelpers { target: compiler.host }); // As well as the target, except for plain wasm32, which can't build it if !target.contains("wasm") || target.contains("emscripten") { - builder.ensure(native::TestHelpers { target }); + builder.ensure(TestHelpers { target }); } builder.ensure(RemoteCopyLibs { compiler, target }); @@ -1623,8 +1623,8 @@ note: if you're sure you want to do this, please open an issue as to why. In the let mut llvm_components_passed = false; let mut copts_passed = false; if builder.config.llvm_enabled() { - let native::LlvmResult { llvm_config, .. } = - builder.ensure(native::Llvm { target: builder.config.build }); + let llvm::LlvmResult { llvm_config, .. } = + builder.ensure(llvm::Llvm { target: builder.config.build }); if !builder.config.dry_run() { let llvm_version = output(Command::new(&llvm_config).arg("--version")); let llvm_components = output(Command::new(&llvm_config).arg("--components")); @@ -1662,7 +1662,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the // If LLD is available, add it to the PATH if builder.config.lld_enabled { let lld_install_root = - builder.ensure(native::Lld { target: builder.config.build }); + builder.ensure(llvm::Lld { target: builder.config.build }); let lld_bin_path = lld_install_root.join("bin"); @@ -2750,3 +2750,68 @@ impl Step for RustInstaller { run.builder.ensure(Self); } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct TestHelpers { + pub target: TargetSelection, +} + +impl Step for TestHelpers { + type Output = (); + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("tests/auxiliary/rust_test_helpers.c") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(TestHelpers { target: run.target }) + } + + /// Compiles the `rust_test_helpers.c` library which we used in various + /// `run-pass` tests for ABI testing. + fn run(self, builder: &Builder<'_>) { + if builder.config.dry_run() { + return; + } + // The x86_64-fortanix-unknown-sgx target doesn't have a working C + // toolchain. However, some x86_64 ELF objects can be linked + // without issues. Use this hack to compile the test helpers. + let target = if self.target == "x86_64-fortanix-unknown-sgx" { + TargetSelection::from_user("x86_64-unknown-linux-gnu") + } else { + self.target + }; + let dst = builder.test_helpers_out(target); + let src = builder.src.join("tests/auxiliary/rust_test_helpers.c"); + if up_to_date(&src, &dst.join("librust_test_helpers.a")) { + return; + } + + builder.info("Building test helpers"); + t!(fs::create_dir_all(&dst)); + let mut cfg = cc::Build::new(); + // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 + if target.contains("emscripten") { + cfg.pic(false); + } + + // We may have found various cross-compilers a little differently due to our + // extra configuration, so inform cc of these compilers. Note, though, that + // on MSVC we still need cc's detection of env vars (ugh). + if !target.contains("msvc") { + if let Some(ar) = builder.ar(target) { + cfg.archiver(ar); + } + cfg.compiler(builder.cc(target)); + } + cfg.cargo_metadata(false) + .out_dir(&dst) + .target(&target.triple) + .host(&builder.config.build.triple) + .opt_level(0) + .warnings(false) + .debug(false) + .file(builder.src.join("tests/auxiliary/rust_test_helpers.c")) + .compile("rust_test_helpers"); + } +} diff --git a/src/ci/stage-build.py b/src/ci/stage-build.py index fe3083dc31e46..8da128c8fe061 100644 --- a/src/ci/stage-build.py +++ b/src/ci/stage-build.py @@ -727,7 +727,7 @@ def record_metrics(pipeline: Pipeline, timer: Timer): metrics = load_last_metrics(pipeline.metrics_path()) if metrics is None: return - llvm_steps = tuple(metrics.find_all_by_type("bootstrap::native::Llvm")) + llvm_steps = tuple(metrics.find_all_by_type("bootstrap::llvm::Llvm")) assert len(llvm_steps) > 0 llvm_duration = sum(step.duration for step in llvm_steps) From 0404e264a23af0f0a3485713843c6525d0e949c8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 13 Mar 2023 17:22:16 +0000 Subject: [PATCH 113/124] Encode opt_rpitit_info for associated types --- compiler/rustc_metadata/src/rmeta/decoder.rs | 5 +++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 ++++++++ compiler/rustc_metadata/src/rmeta/mod.rs | 1 + compiler/rustc_middle/src/ty/parameterized.rs | 1 + compiler/rustc_ty_utils/src/ty.rs | 9 +++------ 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index ca26e1497aaf7..0070e46ffdf02 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1087,6 +1087,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)), }; let container = self.root.tables.assoc_container.get(self, id).unwrap(); + let opt_rpitit_info = + self.root.tables.opt_rpitit_info.get(self, id).map(|d| d.decode(self)); ty::AssocItem { name, @@ -1095,8 +1097,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { trait_item_def_id: self.get_trait_item_def_id(id), container, fn_has_self_parameter: has_self, - // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): We need to encode this - opt_rpitit_info: None, + opt_rpitit_info, } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index bbab8a62a2bce..37b0bfacb8b87 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1350,6 +1350,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if trait_item.kind == ty::AssocKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); } + if let Some(rpitit_info) = trait_item.opt_rpitit_info { + let rpitit_info = self.lazy(rpitit_info); + self.tables.opt_rpitit_info.set_some(def_id.index, rpitit_info); + } } fn encode_info_for_impl_item(&mut self, def_id: DefId) { @@ -1383,6 +1387,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id)); } + if let Some(rpitit_info) = impl_item.opt_rpitit_info { + let rpitit_info = self.lazy(rpitit_info); + self.tables.opt_rpitit_info.set_some(def_id.index, rpitit_info); + } } fn encode_mir(&mut self) { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 1d2541a678819..e71a1c9810249 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -355,6 +355,7 @@ define_tables! { inferred_outlives_of: Table, Span)>>, inherent_impls: Table>, associated_items_for_impl_trait_in_trait: Table>, + opt_rpitit_info: Table>>, - optional: attributes: Table>, diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 8849e7eab335c..7534d06ae91f1 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -63,6 +63,7 @@ trivially_parameterized_over_tcx! { ty::DeducedParamAttrs, ty::Generics, ty::ImplPolarity, + ty::ImplTraitInTraitData, ty::ReprOptions, ty::TraitDef, ty::UnusedGenericParams, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index c8ed1f365f1a8..d41bf603983c0 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -119,12 +119,9 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // When computing the param_env of an RPITIT, copy param_env of the containing function. The // synthesized associated type doesn't have extra predicates to assume. - let def_id = - if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) { - fn_def_id - } else { - def_id - }; + if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) { + return tcx.param_env(fn_def_id); + } // Compute the bounds on Self and the type parameters. let ty::InstantiatedPredicates { mut predicates, .. } = From 3c7df56e11abd80e52e6242d32ab660fdc6f57f3 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 14 Mar 2023 22:54:52 +0000 Subject: [PATCH 114/124] Update cargo 14 commits in 7d3033d2e59383fd76193daf9423c3d141972a7d..4a3c588b1f0a8e2dc8dd8789dbf3b6a71b02ed49 2023-03-08 17:05:08 +0000 to 2023-03-14 14:05:36 +0000 - ci: make clean-test-output a script for reuse (rust-lang/cargo#11848) - Accurately show status when downgrading dependencies (rust-lang/cargo#11839) - docs(contrib): Move Design Principles earlier in the book (rust-lang/cargo#11842) - docs(contrib): Point compilation docs to doc comments (rust-lang/cargo#11841) - `cargo install --git` multiple packages with binaries found hint (rust-lang/cargo#11835) - Disable flaky auth tests when `gitoxide` runs them (rust-lang/cargo#11830) - Add some documentation on writing cross-compilation tests (rust-lang/cargo#11825) - chore: Use sparse protocol on stable CI (rust-lang/cargo#11829) - Notice for potential unexpected shell expansions in help text of `cargo-add` (rust-lang/cargo#11826) - Add tracking issue to gitoxide unstable docs (rust-lang/cargo#11822) - Bump crates-io to 0.36.0 (rust-lang/cargo#11820) - Bump to 0.71.0; update changelog (rust-lang/cargo#11815) - docs(contrib): Move overview to lib (rust-lang/cargo#11809) - Fix semver check for 1.68 (rust-lang/cargo#11817) --- Cargo.lock | 4 ++-- src/tools/cargo | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51332919fe755..0f60e7b8ef4a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -353,7 +353,7 @@ dependencies = [ [[package]] name = "cargo" -version = "0.70.0" +version = "0.71.0" dependencies = [ "anyhow", "base64", @@ -1001,7 +1001,7 @@ dependencies = [ [[package]] name = "crates-io" -version = "0.35.1" +version = "0.36.0" dependencies = [ "anyhow", "curl", diff --git a/src/tools/cargo b/src/tools/cargo index 7d3033d2e5938..4a3c588b1f0a8 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 7d3033d2e59383fd76193daf9423c3d141972a7d +Subproject commit 4a3c588b1f0a8e2dc8dd8789dbf3b6a71b02ed49 From e7c6ad89cfd937d741b9d256e950ec0de96a7142 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 14 Mar 2023 22:24:28 -0700 Subject: [PATCH 115/124] Improved implementation and comments after code review feedback --- .../src/lower_intrinsics.rs | 31 +++--- library/core/src/intrinsics.rs | 14 +-- library/core/src/ptr/mod.rs | 8 +- tests/codegen/ptr-read-metadata.rs | 96 +++++++++++++++++++ tests/codegen/read-noundef-metadata.rs | 51 ---------- ..._via_copy_uninhabited.LowerIntrinsics.diff | 1 - 6 files changed, 124 insertions(+), 77 deletions(-) create mode 100644 tests/codegen/ptr-read-metadata.rs delete mode 100644 tests/codegen/read-noundef-metadata.rs diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 151fff27d14ad..5d7382305ae14 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -150,7 +150,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } } sym::read_via_copy => { - let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else { + let [arg] = args.as_slice() else { span_bug!(terminator.source_info.span, "Wrong number of arguments"); }; let derefed_place = @@ -159,18 +159,23 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } else { span_bug!(terminator.source_info.span, "Only passing a local is supported"); }; - block.statements.push(Statement { - source_info: terminator.source_info, - kind: StatementKind::Assign(Box::new(( - *destination, - Rvalue::Use(Operand::Copy(derefed_place)), - ))), - }); - if let Some(target) = *target { - terminator.kind = TerminatorKind::Goto { target }; - } else { - // Reading something uninhabited means this is unreachable. - terminator.kind = TerminatorKind::Unreachable; + terminator.kind = match *target { + None => { + // No target means this read something uninhabited, + // so it must be unreachable, and we don't need to + // preserve the assignment either. + TerminatorKind::Unreachable + } + Some(target) => { + block.statements.push(Statement { + source_info: terminator.source_info, + kind: StatementKind::Assign(Box::new(( + *destination, + Rvalue::Use(Operand::Copy(derefed_place)), + ))), + }); + TerminatorKind::Goto { target } + } } } sym::discriminant_value => { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index d77c2a00eb780..ee8846675ce25 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2020,16 +2020,12 @@ extern "rust-intrinsic" { #[rustc_safe_intrinsic] pub fn saturating_sub(a: T, b: T) -> T; - /// This is a *typed* read, `copy *p` in MIR. + /// This is an implementation detail of [`crate::ptr::read`] and should + /// not be used anywhere else. See its comments for why this exists. /// - /// The stabilized form of this intrinsic is [`crate::ptr::read`], so - /// that can be implemented without needing to do an *untyped* copy - /// via [`copy_nonoverlapping`], and thus can get proper metadata. - /// - /// This intrinsic can *only* be called with a copy or move of a local. - /// (It allows neither constants nor projections.) - /// - /// To avoid introducing any `noalias` requirements, it just takes a pointer. + /// This intrinsic can *only* be called where the argument is a local without + /// projections (`read_via_copy(p)`, not `read_via_copy(*p)`) so that it + /// trivially obeys runtime-MIR rules about derefs in operands. #[cfg(not(bootstrap))] #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] pub fn read_via_copy(p: *const T) -> T; diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 86929e2c4889c..5884a8ca30807 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1136,10 +1136,12 @@ pub const unsafe fn replace(dst: *mut T, mut src: T) -> T { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn read(src: *const T) -> T { // It would be semantically correct to implement this via `copy_nonoverlapping` - // and `MaybeUninit`, as was done before PR #109035. + // and `MaybeUninit`, as was done before PR #109035. Calling `assume_init` + // provides enough information to know that this is a typed operation. - // However, it switched to intrinsic that lowers to `_0 = *src` in MIR in - // order to address a few implementation issues: + // However, as of March 2023 the compiler was not capable of taking advantage + // of that information. Thus the implementation here switched to an intrinsic, + // which lowers to `_0 = *src` in MIR, to address a few issues: // // - Using `MaybeUninit::assume_init` after a `copy_nonoverlapping` was not // turning the untyped copy into a typed load. As such, the generated diff --git a/tests/codegen/ptr-read-metadata.rs b/tests/codegen/ptr-read-metadata.rs new file mode 100644 index 0000000000000..e1e3272662c4b --- /dev/null +++ b/tests/codegen/ptr-read-metadata.rs @@ -0,0 +1,96 @@ +// compile-flags: -O -Z merge-functions=disabled +// no-system-llvm +// ignore-debug (the extra assertions get in the way) + +#![crate_type = "lib"] + +// Ensure that various forms of reading pointers correctly annotate the `load`s +// with `!noundef` and `!range` metadata to enable extra optimization. + +use std::mem::MaybeUninit; + +// CHECK-LABEL: define noundef i8 @copy_byte( +#[no_mangle] +pub unsafe fn copy_byte(p: *const u8) -> u8 { + // CHECK-NOT: load + // CHECK: load i8, ptr %p, align 1 + // CHECK-SAME: !noundef ! + // CHECK-NOT: load + *p +} + +// CHECK-LABEL: define noundef i8 @read_byte( +#[no_mangle] +pub unsafe fn read_byte(p: *const u8) -> u8 { + // CHECK-NOT: load + // CHECK: load i8, ptr %p, align 1 + // CHECK-SAME: !noundef ! + // CHECK-NOT: load + p.read() +} + +// CHECK-LABEL: define i8 @read_byte_maybe_uninit( +#[no_mangle] +pub unsafe fn read_byte_maybe_uninit(p: *const MaybeUninit) -> MaybeUninit { + // CHECK-NOT: load + // CHECK: load i8, ptr %p, align 1 + // CHECK-NOT: noundef + // CHECK-NOT: load + p.read() +} + +// CHECK-LABEL: define noundef i8 @read_byte_assume_init( +#[no_mangle] +pub unsafe fn read_byte_assume_init(p: &MaybeUninit) -> u8 { + // CHECK-NOT: load + // CHECK: load i8, ptr %p, align 1 + // CHECK-SAME: !noundef ! + // CHECK-NOT: load + p.assume_init_read() +} + +// CHECK-LABEL: define noundef i32 @copy_char( +#[no_mangle] +pub unsafe fn copy_char(p: *const char) -> char { + // CHECK-NOT: load + // CHECK: load i32, ptr %p + // CHECK-SAME: !range ![[RANGE:[0-9]+]] + // CHECK-SAME: !noundef ! + // CHECK-NOT: load + *p +} + +// CHECK-LABEL: define noundef i32 @read_char( +#[no_mangle] +pub unsafe fn read_char(p: *const char) -> char { + // CHECK-NOT: load + // CHECK: load i32, ptr %p + // CHECK-SAME: !range ![[RANGE]] + // CHECK-SAME: !noundef ! + // CHECK-NOT: load + p.read() +} + +// CHECK-LABEL: define i32 @read_char_maybe_uninit( +#[no_mangle] +pub unsafe fn read_char_maybe_uninit(p: *const MaybeUninit) -> MaybeUninit { + // CHECK-NOT: load + // CHECK: load i32, ptr %p + // CHECK-NOT: range + // CHECK-NOT: noundef + // CHECK-NOT: load + p.read() +} + +// CHECK-LABEL: define noundef i32 @read_char_assume_init( +#[no_mangle] +pub unsafe fn read_char_assume_init(p: &MaybeUninit) -> char { + // CHECK-NOT: load + // CHECK: load i32, ptr %p + // CHECK-SAME: !range ![[RANGE]] + // CHECK-SAME: !noundef ! + // CHECK-NOT: load + p.assume_init_read() +} + +// CHECK: ![[RANGE]] = !{i32 0, i32 1114112} diff --git a/tests/codegen/read-noundef-metadata.rs b/tests/codegen/read-noundef-metadata.rs deleted file mode 100644 index 03386921c43e3..0000000000000 --- a/tests/codegen/read-noundef-metadata.rs +++ /dev/null @@ -1,51 +0,0 @@ -// compile-flags: -O -Z merge-functions=disabled -// no-system-llvm -// ignore-debug (the extra assertions get in the way) - -#![crate_type = "lib"] - -// Ensure that various forms of reading pointers correctly annotate the `load`s -// with `!noundef` metadata to enable extra optimization. The functions return -// `MaybeUninit` to keep it from being inferred from the function type. - -use std::mem::MaybeUninit; - -// CHECK-LABEL: define i8 @copy_byte( -#[no_mangle] -pub unsafe fn copy_byte(p: *const u8) -> MaybeUninit { - // CHECK-NOT: load - // CHECK: load i8, ptr %p, align 1 - // CHECK-SAME: !noundef ! - // CHECK-NOT: load - MaybeUninit::new(*p) -} - -// CHECK-LABEL: define i8 @read_byte( -#[no_mangle] -pub unsafe fn read_byte(p: *const u8) -> MaybeUninit { - // CHECK-NOT: load - // CHECK: load i8, ptr %p, align 1 - // CHECK-SAME: !noundef ! - // CHECK-NOT: load - MaybeUninit::new(p.read()) -} - -// CHECK-LABEL: define i8 @read_byte_maybe_uninit( -#[no_mangle] -pub unsafe fn read_byte_maybe_uninit(p: *const MaybeUninit) -> MaybeUninit { - // CHECK-NOT: load - // CHECK: load i8, ptr %p, align 1 - // CHECK-NOT: noundef - // CHECK-NOT: load - p.read() -} - -// CHECK-LABEL: define i8 @read_byte_assume_init( -#[no_mangle] -pub unsafe fn read_byte_assume_init(p: &MaybeUninit) -> MaybeUninit { - // CHECK-NOT: load - // CHECK: load i8, ptr %p, align 1 - // CHECK-SAME: !noundef ! - // CHECK-NOT: load - MaybeUninit::new(p.assume_init_read()) -} diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff index faf3f9c31b82f..610c67d2fecd6 100644 --- a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff @@ -15,7 +15,6 @@ - // mir::Constant - // + span: $DIR/lower_intrinsics.rs:90:14: 90:45 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Never) -> Never {read_via_copy::}, val: Value() } -+ _0 = (*_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 + unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 } } From b3af5e2f8b58c96704d6a26a7a0e25b3b2bec6ad Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 15 Mar 2023 09:09:01 +0800 Subject: [PATCH 116/124] Fix #109152, fix the scenario that we may can not get span of func --- compiler/rustc_lint/src/map_unit_fn.rs | 11 +++++++++-- tests/ui/lint/issue-109152.rs | 7 +++++++ tests/ui/lint/issue-109152.stderr | 23 +++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 tests/ui/lint/issue-109152.rs create mode 100644 tests/ui/lint/issue-109152.stderr diff --git a/compiler/rustc_lint/src/map_unit_fn.rs b/compiler/rustc_lint/src/map_unit_fn.rs index 62e8b4fe9e4a2..7c692fee33389 100644 --- a/compiler/rustc_lint/src/map_unit_fn.rs +++ b/compiler/rustc_lint/src/map_unit_fn.rs @@ -56,6 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn { return; } let arg_ty = cx.typeck_results().expr_ty(&args[0]); + let default_span = args[0].span; if let ty::FnDef(id, _) = arg_ty.kind() { let fn_ty = cx.tcx.fn_sig(id).skip_binder(); let ret_ty = fn_ty.output().skip_binder(); @@ -64,7 +65,10 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn { MAP_UNIT_FN, span, MappingToUnit { - function_label: cx.tcx.span_of_impl(*id).unwrap(), + function_label: cx + .tcx + .span_of_impl(*id) + .unwrap_or(default_span), argument_label: args[0].span, map_label: arg_ty.default_span(cx.tcx), suggestion: path.ident.span, @@ -80,7 +84,10 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn { MAP_UNIT_FN, span, MappingToUnit { - function_label: cx.tcx.span_of_impl(*id).unwrap(), + function_label: cx + .tcx + .span_of_impl(*id) + .unwrap_or(default_span), argument_label: args[0].span, map_label: arg_ty.default_span(cx.tcx), suggestion: path.ident.span, diff --git a/tests/ui/lint/issue-109152.rs b/tests/ui/lint/issue-109152.rs new file mode 100644 index 0000000000000..daf530e6d0b6e --- /dev/null +++ b/tests/ui/lint/issue-109152.rs @@ -0,0 +1,7 @@ +#![deny(map_unit_fn)] + +#![crate_type = "lib"] +fn _y() { + vec![42].iter().map(drop); + //~^ ERROR `Iterator::map` call that discard the iterator's values +} diff --git a/tests/ui/lint/issue-109152.stderr b/tests/ui/lint/issue-109152.stderr new file mode 100644 index 0000000000000..7db9e71a584b0 --- /dev/null +++ b/tests/ui/lint/issue-109152.stderr @@ -0,0 +1,23 @@ +error: `Iterator::map` call that discard the iterator's values + --> $DIR/issue-109152.rs:5:21 + | +LL | vec![42].iter().map(drop); + | ^^^^----^ + | | | + | | this function returns `()`, which is likely not what you wanted + | | called `Iterator::map` with callable that returns `()` + | after this call to map, the resulting iterator is `impl Iterator`, which means the only information carried by the iterator is the number of items + | + = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated +note: the lint level is defined here + --> $DIR/issue-109152.rs:1:9 + | +LL | #![deny(map_unit_fn)] + | ^^^^^^^^^^^ +help: you might have meant to use `Iterator::for_each` + | +LL | vec![42].iter().for_each(drop); + | ~~~~~~~~ + +error: aborting due to previous error + From dfc3377954f9e03172fed57ca890141006a0d82e Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 15 Mar 2023 00:57:08 -0700 Subject: [PATCH 117/124] Split the mem-replace codegen test Apparently in CI it's getting generated in the opposite order, one function per file will make the test pass either way. --- tests/codegen/mem-replace-big-type.rs | 36 ++++++++++++++++++++++ tests/codegen/mem-replace-direct-memcpy.rs | 22 ------------- 2 files changed, 36 insertions(+), 22 deletions(-) create mode 100644 tests/codegen/mem-replace-big-type.rs diff --git a/tests/codegen/mem-replace-big-type.rs b/tests/codegen/mem-replace-big-type.rs new file mode 100644 index 0000000000000..f6898e2f75814 --- /dev/null +++ b/tests/codegen/mem-replace-big-type.rs @@ -0,0 +1,36 @@ +// This test ensures that `mem::replace::` only ever calls `@llvm.memcpy` +// with `size_of::()` as the size, and never goes through any wrapper that +// may e.g. multiply `size_of::()` with a variable "count" (which is only +// known to be `1` after inlining). + +// compile-flags: -C no-prepopulate-passes -Zinline-mir=no +// ignore-debug: the debug assertions get in the way + +#![crate_type = "lib"] + +#[repr(C, align(8))] +pub struct Big([u64; 7]); +pub fn replace_big(dst: &mut Big, src: Big) -> Big { + // Before the `read_via_copy` intrinsic, this emitted six `memcpy`s. + std::mem::replace(dst, src) +} + +// NOTE(eddyb) the `CHECK-NOT`s ensure that the only calls of `@llvm.memcpy` in +// the entire output, are the direct calls we want, from `ptr::replace`. + +// CHECK-NOT: call void @llvm.memcpy + +// For a large type, we expect exactly three `memcpy`s +// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big) + // CHECK-NOT: alloca + // CHECK: alloca %Big + // CHECK-NOT: alloca + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) + // CHECK-NOT: call void @llvm.memcpy + +// CHECK-NOT: call void @llvm.memcpy diff --git a/tests/codegen/mem-replace-direct-memcpy.rs b/tests/codegen/mem-replace-direct-memcpy.rs index 3b01a621b5680..83babab4f847b 100644 --- a/tests/codegen/mem-replace-direct-memcpy.rs +++ b/tests/codegen/mem-replace-direct-memcpy.rs @@ -12,33 +12,11 @@ pub fn replace_byte(dst: &mut u8, src: u8) -> u8 { std::mem::replace(dst, src) } -#[repr(C, align(8))] -pub struct Big([u64; 7]); -pub fn replace_big(dst: &mut Big, src: Big) -> Big { - // Before the `read_via_copy` intrinsic, this emitted six `memcpy`s. - std::mem::replace(dst, src) -} - // NOTE(eddyb) the `CHECK-NOT`s ensure that the only calls of `@llvm.memcpy` in // the entire output, are the direct calls we want, from `ptr::replace`. // CHECK-NOT: call void @llvm.memcpy -// For a large type, we expect exactly three `memcpy`s -// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big) - // CHECK-NOT: alloca - // CHECK: alloca %Big - // CHECK-NOT: alloca - // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) - // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) - // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %{{.*}}, {{i8\*|ptr}} align 8 %{{.*}}, i{{.*}} 56, i1 false) - // CHECK-NOT: call void @llvm.memcpy - -// CHECK-NOT: call void @llvm.memcpy - // For a small type, we expect one each of `load`/`store`/`memcpy` instead // CHECK-LABEL: define internal noundef i8 @{{.+}}mem{{.+}}replace // CHECK-NOT: alloca From a9f3db62126834ab0bcd18d1412a88ba1e88e0a8 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 15 Mar 2023 10:17:03 +0100 Subject: [PATCH 118/124] Remove mw from review rotation. --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index a81f66fe16856..9ffe2e72cabea 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -492,7 +492,6 @@ compiler-team = [ "@oli-obk", "@lcnr", "@wesleywiser", - "@michaelwoerister", ] compiler-team-contributors = [ "@compiler-errors", From 2e7249fa0f4c276414b7905b1ad975bd98da0c55 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Fri, 10 Mar 2023 19:47:09 +0300 Subject: [PATCH 119/124] add `enable-warnings` flag for llvm Signed-off-by: ozkanonur --- config.example.toml | 3 +++ src/bootstrap/CHANGELOG.md | 1 + src/bootstrap/config.rs | 3 +++ src/bootstrap/defaults/config.codegen.toml | 2 ++ src/bootstrap/native.rs | 9 +++------ 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/config.example.toml b/config.example.toml index dee0d8f254b63..7ae46203f972a 100644 --- a/config.example.toml +++ b/config.example.toml @@ -146,6 +146,9 @@ changelog-seen = 2 # Whether to build the clang compiler. #clang = false +# Whether to enable llvm compilation warnings. +#enable-warnings = false + # Custom CMake defines to set when building LLVM. #build-config = {} diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index 54d0d8a8ec25e..654e03d0c3c7f 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -25,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - If you have Rust already installed, `x.py` will now infer the host target from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513) - Add options for enabling overflow checks, one for std (`overflow-checks-std`) and one for everything else (`overflow-checks`). Both default to false. +- Add llvm option `enable-warnings` to have control on llvm compilation warnings. Default to false. ## [Version 2] - 2020-09-25 diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index fc5aa8a245d2d..58729f396f0b6 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -133,6 +133,7 @@ pub struct Config { pub llvm_allow_old_toolchain: bool, pub llvm_polly: bool, pub llvm_clang: bool, + pub llvm_enable_warnings: bool, pub llvm_from_ci: bool, pub llvm_build_config: HashMap, @@ -688,6 +689,7 @@ define_config! { allow_old_toolchain: Option = "allow-old-toolchain", polly: Option = "polly", clang: Option = "clang", + enable_warnings: Option = "enable-warnings", download_ci_llvm: Option = "download-ci-llvm", build_config: Option> = "build-config", } @@ -1184,6 +1186,7 @@ impl Config { config.llvm_allow_old_toolchain = llvm.allow_old_toolchain.unwrap_or(false); config.llvm_polly = llvm.polly.unwrap_or(false); config.llvm_clang = llvm.clang.unwrap_or(false); + config.llvm_enable_warnings = llvm.enable_warnings.unwrap_or(false); config.llvm_build_config = llvm.build_config.clone().unwrap_or(Default::default()); let asserts = llvm_assertions.unwrap_or(false); diff --git a/src/bootstrap/defaults/config.codegen.toml b/src/bootstrap/defaults/config.codegen.toml index eb2afa555f183..20b2699c761bf 100644 --- a/src/bootstrap/defaults/config.codegen.toml +++ b/src/bootstrap/defaults/config.codegen.toml @@ -7,6 +7,8 @@ compiler-docs = true # This enables debug-assertions in LLVM, # catching logic errors in codegen much earlier in the process. assertions = true +# enable warnings during the llvm compilation +enable-warnings = true [rust] # This enables `RUSTC_LOG=debug`, avoiding confusing situations diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 040e36ea5f8d8..41ee509655326 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -304,6 +304,7 @@ impl Step for Llvm { let assertions = if builder.config.llvm_assertions { "ON" } else { "OFF" }; let plugins = if builder.config.llvm_plugins { "ON" } else { "OFF" }; let enable_tests = if builder.config.llvm_tests { "ON" } else { "OFF" }; + let enable_warnings = if builder.config.llvm_enable_warnings { "ON" } else { "OFF" }; cfg.out_dir(&out_dir) .profile(profile) @@ -321,7 +322,8 @@ impl Step for Llvm { .define("LLVM_ENABLE_Z3_SOLVER", "OFF") .define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string()) .define("LLVM_TARGET_ARCH", target_native.split('-').next().unwrap()) - .define("LLVM_DEFAULT_TARGET_TRIPLE", target_native); + .define("LLVM_DEFAULT_TARGET_TRIPLE", target_native) + .define("LLVM_ENABLE_WARNINGS", enable_warnings); // Parts of our test suite rely on the `FileCheck` tool, which is built by default in // `build/$TARGET/llvm/build/bin` is but *not* then installed to `build/$TARGET/llvm/bin`. @@ -483,11 +485,6 @@ impl Step for Llvm { cfg.define(key, val); } - // FIXME: we don't actually need to build all LLVM tools and all LLVM - // libraries here, e.g., we just want a few components and a few - // tools. Figure out how to filter them down and only build the right - // tools and libs on all platforms. - if builder.config.dry_run() { return res; } From b42358a23f145688f048145be2ac9fe4f6b36335 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 15 Mar 2023 14:19:15 +0000 Subject: [PATCH 120/124] Use patched git-subtree from bjorn3/git@tqc-subtree-portable This patched has been necessary for subtree syncs from the start, but previously it was necessary to locally install tqc's patched git version, which hasn't been updated for quite a while. I made a small change to allow downloading it as script without requiring an entire git installation for the patched version. --- .gitignore | 1 + scripts/rustup.sh | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 8012e93f6a90e..e5d10a937ae24 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ perf.data.old /dist /rust /download +/git-fixed-subtree.sh diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 75219c82e82e0..3cbeb6375de10 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -4,6 +4,20 @@ set -e TOOLCHAIN=${TOOLCHAIN:-$(date +%Y-%m-%d)} +function check_git_fixed_subtree() { + if [[ ! -e ./git-fixed-subtree.sh ]]; then + echo "Missing git-fixed-subtree.sh. Please run the following commands to download it:" + echo "curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/bjorn3/git/tqc-subtree-portable/contrib/subtree/git-subtree.sh -o git-fixed-subtree.sh" + echo "chmod u+x git-fixed-subtree.sh" + exit 1 + fi + if [[ ! -x ./git-fixed-subtree.sh ]]; then + echo "git-fixed-subtree.sh is not executable. Please run the following command to make it executable:" + echo "chmod u+x git-fixed-subtree.sh" + exit 1 + fi +} + case $1 in "prepare") echo "=> Installing new nightly" @@ -27,21 +41,25 @@ case $1 in git commit -m "Rustup to $(rustc -V)" ;; "push") + check_git_fixed_subtree + cg_clif=$(pwd) pushd ../rust git pull origin master branch=sync_cg_clif-$(date +%Y-%m-%d) git checkout -b "$branch" - git subtree pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/bjorn3/rustc_codegen_cranelift.git master + "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/bjorn3/rustc_codegen_cranelift.git master git push -u my "$branch" # immediately merge the merge commit into cg_clif to prevent merge conflicts when syncing # from rust-lang/rust later - git subtree push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust + "$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust popd git merge sync_from_rust ;; "pull") + check_git_fixed_subtree + RUST_VERS=$(curl "https://static.rust-lang.org/dist/$TOOLCHAIN/channel-rust-nightly-git-commit-hash.txt") echo "Pulling $RUST_VERS ($TOOLCHAIN)" @@ -49,7 +67,7 @@ case $1 in pushd ../rust git fetch origin master git checkout "$RUST_VERS" - git subtree push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust + "$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust popd git merge sync_from_rust -m "Sync from rust $RUST_VERS" git branch -d sync_from_rust From 6f6007156b2ddd5ceee356db5d79f4491bf011f3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 15 Mar 2023 14:26:03 +0000 Subject: [PATCH 121/124] Introduce Box::new in mini_core --- example/mini_core.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/example/mini_core.rs b/example/mini_core.rs index 1f9db1eb2a97a..73b83b89f6d91 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -518,6 +518,17 @@ pub struct Box(Unique, ()); impl, U: ?Sized> CoerceUnsized> for Box {} +impl Box { + pub fn new(val: T) -> Box { + unsafe { + let size = intrinsics::size_of::(); + let ptr = libc::malloc(size); + intrinsics::copy(&val as *const T as *const u8, ptr, size); + Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, ()) + } + } +} + impl Drop for Box { fn drop(&mut self) { // drop is currently performed by compiler. From dec0daa8f6d0a0e1c702f169abb6bf3eee198c67 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 15 Mar 2023 14:33:54 +0000 Subject: [PATCH 122/124] Rustup to rustc 1.70.0-nightly (171693274 2023-03-14) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index f86eb7a2b53d8..2236a6ca15521 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-03-13" +channel = "nightly-2023-03-15" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 5ad1083e5bb6dfea0f4368031466b4f366dabf79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 15 Mar 2023 15:09:29 +0000 Subject: [PATCH 123/124] Revert "Auto merge of #107376 - aliemjay:remove-givens, r=lcnr" This reverts commit e84e5ff04a647ce28540300244a26ba120642eea, reversing changes made to 1716932743a7b3705cbf0c34db0c4e070ed1930d. --- .../src/check/compare_impl_item.rs | 5 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- .../src/impl_wf_check/min_specialization.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 9 ++- .../src/infer/canonical/query_response.rs | 4 +- .../src/infer/lexical_region_resolve/mod.rs | 47 ++++++++++++++- compiler/rustc_infer/src/infer/mod.rs | 4 ++ .../rustc_infer/src/infer/outlives/env.rs | 45 +++++++++----- .../infer/region_constraints/leak_check.rs | 3 + .../src/infer/region_constraints/mod.rs | 44 +++++++++++++- .../src/traits/coherence.rs | 1 + .../rustc_trait_selection/src/traits/misc.rs | 1 + .../src/traits/outlives_bounds.rs | 12 ++-- tests/ui/implied-bounds/normalization.rs | 58 ------------------- 14 files changed, 152 insertions(+), 87 deletions(-) delete mode 100644 tests/ui/implied-bounds/normalization.rs diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 123207249d27d..6e6f8c1533bfe 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -330,6 +330,7 @@ fn compare_method_predicate_entailment<'tcx>( // lifetime parameters. let outlives_env = OutlivesEnvironment::with_bounds( param_env, + Some(infcx), infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys.clone()), ); infcx.process_registered_region_obligations( @@ -727,6 +728,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // lifetime parameters. let outlives_environment = OutlivesEnvironment::with_bounds( param_env, + Some(infcx), infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys), ); infcx @@ -2056,7 +2058,8 @@ pub(super) fn check_type_bounds<'tcx>( // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, assumed_wf_types); - let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds); + let outlives_environment = + OutlivesEnvironment::with_bounds(param_env, Some(&infcx), implied_bounds); infcx.err_ctxt().check_region_obligations_and_report_errors( impl_ty.def_id.expect_local(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 28f0924d1d683..71050864ce0c5 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -115,7 +115,8 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( return; } - let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds); + let outlives_environment = + OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds); let _ = infcx .err_ctxt() @@ -675,6 +676,7 @@ fn resolve_regions_with_wf_tys<'tcx>( let infcx = tcx.infer_ctxt().build(); let outlives_environment = OutlivesEnvironment::with_bounds( param_env, + Some(&infcx), infcx.implied_bounds_tys(param_env, id, wf_tys.clone()), ); let region_bound_pairs = outlives_environment.region_bound_pairs(); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 1c5860e97bcb3..58dd03811f78c 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -179,7 +179,7 @@ fn get_impl_substs( } let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types); - let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); + let outlives_env = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds); let _ = infcx.err_ctxt().check_region_obligations_and_report_errors(impl1_def_id, &outlives_env); let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 11ff65d0c373a..c36c75e444368 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -238,8 +238,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Note that there are two tests to check that this remains true // (`regions-reassign-{match,let}-bound-pointer.rs`). // - // 2. An outdated issue related to the old HIR borrowck. See the test + // 2. Things go horribly wrong if we use subtype. The reason for + // THIS is a fairly subtle case involving bound regions. See the + // `givens` field in `region_constraints`, as well as the test // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`, + // for details. Short version is that we must sometimes detect + // relationships between specific region variables and regions + // bound in a closure signature, and that detection gets thrown + // off when we substitute fresh region variables here to enable + // subtyping. } /// Compute the new expected type and default binding mode from the old ones diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 90e89a187822d..436d29c2449e4 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -636,9 +636,11 @@ pub fn make_query_region_constraints<'tcx>( outlives_obligations: impl Iterator, ty::Region<'tcx>, ConstraintCategory<'tcx>)>, region_constraints: &RegionConstraintData<'tcx>, ) -> QueryRegionConstraints<'tcx> { - let RegionConstraintData { constraints, verifys, member_constraints } = region_constraints; + let RegionConstraintData { constraints, verifys, givens, member_constraints } = + region_constraints; assert!(verifys.is_empty()); + assert!(givens.is_empty()); debug!(?constraints); diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index cf657756ff534..2c480355085ef 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; use rustc_data_structures::intern::Interned; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::PlaceholderRegion; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -132,6 +132,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } let graph = self.construct_graph(); + self.expand_givens(&graph); self.expansion(&mut var_data); self.collect_errors(&mut var_data, errors); self.collect_var_errors(&var_data, &graph, errors); @@ -163,6 +164,38 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } + fn expand_givens(&mut self, graph: &RegionGraph<'_>) { + // Givens are a kind of horrible hack to account for + // constraints like 'c <= '0 that are known to hold due to + // closure signatures (see the comment above on the `givens` + // field). They should go away. But until they do, the role + // of this fn is to account for the transitive nature: + // + // Given 'c <= '0 + // and '0 <= '1 + // then 'c <= '1 + + let seeds: Vec<_> = self.data.givens.iter().cloned().collect(); + for (r, vid) in seeds { + // While all things transitively reachable in the graph + // from the variable (`'0` in the example above). + let seed_index = NodeIndex(vid.index() as usize); + for succ_index in graph.depth_traverse(seed_index, OUTGOING) { + let succ_index = succ_index.0; + + // The first N nodes correspond to the region + // variables. Other nodes correspond to constant + // regions. + if succ_index < self.num_vars() { + let succ_vid = RegionVid::new(succ_index); + + // Add `'c <= '1`. + self.data.givens.insert((r, succ_vid)); + } + } + } + } + /// Gets the LUb of a given region and the empty region fn lub_empty(&self, a_region: Region<'tcx>) -> Result, PlaceholderRegion> { match *a_region { @@ -329,6 +362,18 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ) -> bool { debug!("expand_node({:?}, {:?} == {:?})", a_region, b_vid, b_data); + match *a_region { + // Check if this relationship is implied by a given. + ty::ReEarlyBound(_) | ty::ReFree(_) => { + if self.data.givens.contains(&(a_region, b_vid)) { + debug!("given"); + return false; + } + } + + _ => {} + } + match *b_data { VarValue::Empty(empty_ui) => { let lub = match self.lub_empty(a_region) { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 66fb1db46185d..4a834957959db 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -855,6 +855,10 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot) } + pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) { + self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); + } + pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool where T: at::ToTrace<'tcx>, diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index a480ee5429eec..24e3c34dd94fc 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -1,9 +1,9 @@ use crate::infer::free_regions::FreeRegionMap; -use crate::infer::GenericKind; +use crate::infer::{GenericKind, InferCtxt}; use crate::traits::query::OutlivesBound; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::transitive_relation::TransitiveRelationBuilder; -use rustc_middle::ty::{self, Region}; +use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region}; use super::explicit_outlives_bounds; @@ -75,7 +75,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> { region_bound_pairs: Default::default(), }; - builder.add_outlives_bounds(explicit_outlives_bounds(param_env)); + builder.add_outlives_bounds(None, explicit_outlives_bounds(param_env)); builder } @@ -89,10 +89,11 @@ impl<'tcx> OutlivesEnvironment<'tcx> { /// Create a new `OutlivesEnvironment` with extra outlives bounds. pub fn with_bounds( param_env: ty::ParamEnv<'tcx>, + infcx: Option<&InferCtxt<'tcx>>, extra_bounds: impl IntoIterator>, ) -> Self { let mut builder = Self::builder(param_env); - builder.add_outlives_bounds(extra_bounds); + builder.add_outlives_bounds(infcx, extra_bounds); builder.build() } @@ -119,7 +120,12 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { } /// Processes outlives bounds that are known to hold, whether from implied or other sources. - fn add_outlives_bounds(&mut self, outlives_bounds: I) + /// + /// The `infcx` parameter is optional; if the implied bounds may + /// contain inference variables, it must be supplied, in which + /// case we will register "givens" on the inference context. (See + /// `RegionConstraintData`.) + fn add_outlives_bounds(&mut self, infcx: Option<&InferCtxt<'tcx>>, outlives_bounds: I) where I: IntoIterator>, { @@ -136,14 +142,27 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { self.region_bound_pairs .insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a)); } - OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) { - ( - ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_), - ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_), - ) => self.region_relation.add(r_a, r_b), - (ty::ReError(_), _) | (_, ty::ReError(_)) => {} - _ => bug!("add_outlives_bounds: unexpected regions"), - }, + OutlivesBound::RegionSubRegion(r_a, r_b) => { + if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) { + infcx + .expect("no infcx provided but region vars found") + .add_given(r_a, vid_b); + } else { + // In principle, we could record (and take + // advantage of) every relationship here, but + // we are also free not to -- it simply means + // strictly less that we can successfully type + // check. Right now we only look for things + // relationships between free regions. (It may + // also be that we should revise our inference + // system to be more general and to make use + // of *every* relationship that arises here, + // but presently we do not.) + if r_a.is_free_or_static() && r_b.is_free() { + self.region_relation.add(r_a, r_b) + } + } + } } } } diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 89ada23c6673a..e413b2bb570d6 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -424,6 +424,9 @@ impl<'tcx> MiniGraph<'tcx> { &AddConstraint(Constraint::RegSubReg(a, b)) => { each_edge(a, b); } + &AddGiven(a, b) => { + each_edge(a, tcx.mk_re_var(b)); + } &AddVerify(i) => span_bug!( verifys[i].origin.span(), "we never add verifications while doing higher-ranked things", diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 7b272dfd2a454..0b86d9c1fb827 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -7,7 +7,7 @@ use super::{ InferCtxtUndoLogs, MiscVariable, RegionVariableOrigin, Rollback, Snapshot, SubregionOrigin, }; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::UndoLogs; @@ -104,6 +104,26 @@ pub struct RegionConstraintData<'tcx> { /// An example is a `A <= B` where neither `A` nor `B` are /// inference variables. pub verifys: Vec>, + + /// A "given" is a relationship that is known to hold. In + /// particular, we often know from closure fn signatures that a + /// particular free region must be a subregion of a region + /// variable: + /// + /// foo.iter().filter(<'a> |x: &'a &'b T| ...) + /// + /// In situations like this, `'b` is in fact a region variable + /// introduced by the call to `iter()`, and `'a` is a bound region + /// on the closure (as indicated by the `<'a>` prefix). If we are + /// naive, we wind up inferring that `'b` must be `'static`, + /// because we require that it be greater than `'a` and we do not + /// know what `'a` is precisely. + /// + /// This hashmap is used to avoid that naive scenario. Basically + /// we record the fact that `'a <= 'b` is implied by the fn + /// signature, and then ignore the constraint when solving + /// equations. This is a bit of a hack but seems to work. + pub givens: FxIndexSet<(Region<'tcx>, ty::RegionVid)>, } /// Represents a constraint that influences the inference process. @@ -277,6 +297,9 @@ pub(crate) enum UndoLog<'tcx> { /// We added the given `verify`. AddVerify(usize), + /// We added the given `given`. + AddGiven(Region<'tcx>, ty::RegionVid), + /// We added a GLB/LUB "combination variable". AddCombination(CombineMapType, TwoRegions<'tcx>), } @@ -325,6 +348,9 @@ impl<'tcx> RegionConstraintStorage<'tcx> { self.data.verifys.pop(); assert_eq!(self.data.verifys.len(), index); } + AddGiven(sub, sup) => { + self.data.givens.remove(&(sub, sup)); + } AddCombination(Glb, ref regions) => { self.glbs.remove(regions); } @@ -466,6 +492,15 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.undo_log.push(AddVerify(index)); } + pub(super) fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) { + // cannot add givens once regions are resolved + if self.data.givens.insert((sub, sup)) { + debug!("add_given({:?} <= {:?})", sub, sup); + + self.undo_log.push(AddGiven(sub, sup)); + } + } + pub(super) fn make_eqregion( &mut self, origin: SubregionOrigin<'tcx>, @@ -769,8 +804,11 @@ impl<'tcx> RegionConstraintData<'tcx> { /// Returns `true` if this region constraint data contains no constraints, and `false` /// otherwise. pub fn is_empty(&self) -> bool { - let RegionConstraintData { constraints, member_constraints, verifys } = self; - constraints.is_empty() && member_constraints.is_empty() && verifys.is_empty() + let RegionConstraintData { constraints, member_constraints, verifys, givens } = self; + constraints.is_empty() + && member_constraints.is_empty() + && verifys.is_empty() + && givens.is_empty() } } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index aeaade1d66c2b..96a4b76af550f 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -388,6 +388,7 @@ fn resolve_negative_obligation<'tcx>( let wf_tys = ocx.assumed_wf_types(param_env, DUMMY_SP, body_def_id); let outlives_env = OutlivesEnvironment::with_bounds( param_env, + Some(&infcx), infcx.implied_bounds_tys(param_env, body_def_id, wf_tys), ); diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 0bde43c54df99..336db4fee6ced 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -111,6 +111,7 @@ pub fn type_allowed_to_implement_copy<'tcx>( // Check regions assuming the self type of the impl is WF let outlives_env = OutlivesEnvironment::with_bounds( param_env, + Some(&infcx), infcx.implied_bounds_tys( param_env, parent_cause.body_id, diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index e2c198fabde6d..6cb64ad574f5b 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -3,8 +3,7 @@ use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput}; use crate::traits::query::NoSolution; use crate::traits::ObligationCause; use rustc_data_structures::fx::FxIndexSet; -use rustc_infer::infer::resolve::OpportunisticRegionResolver; -use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt}; +use rustc_middle::ty::{self, ParamEnv, Ty}; use rustc_span::def_id::LocalDefId; pub use rustc_middle::traits::query::OutlivesBound; @@ -53,10 +52,6 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { body_id: LocalDefId, ty: Ty<'tcx>, ) -> Vec> { - let ty = self.resolve_vars_if_possible(ty); - let ty = OpportunisticRegionResolver::new(self).fold_ty(ty); - assert!(!ty.needs_infer()); - let span = self.tcx.def_span(body_id); let result = param_env .and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty }) @@ -110,7 +105,10 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { tys: FxIndexSet>, ) -> Bounds<'a, 'tcx> { tys.into_iter() - .map(move |ty| self.implied_outlives_bounds(param_env, body_id, ty)) + .map(move |ty| { + let ty = self.resolve_vars_if_possible(ty); + self.implied_outlives_bounds(param_env, body_id, ty) + }) .flatten() } } diff --git a/tests/ui/implied-bounds/normalization.rs b/tests/ui/implied-bounds/normalization.rs deleted file mode 100644 index f776fc98a9ede..0000000000000 --- a/tests/ui/implied-bounds/normalization.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Test that we get implied bounds from complex projections after normalization. - -// check-pass - -// implementations wil ensure that -// WF(>::Ty) implies T: 'a -trait Combine<'a> { - type Ty; -} - -impl<'a, T: 'a> Combine<'a> for Box { - type Ty = &'a T; -} - -// ======= Wrappers ====== - -// normalizes to a projection -struct WrapA(T); -impl<'a, T> Combine<'a> for WrapA -where - T: Combine<'a>, -{ - type Ty = T::Ty; -} - -// as Combine<'a>>::Ty normalizes to a type variable ?X -// with constraint `>::Ty == ?X` -struct WrapB(T); -impl<'a, X, T> Combine<'a> for WrapB -where - T: Combine<'a, Ty = X>, -{ - type Ty = X; -} - -// as Combine<'a>>::Ty normalizes to `&'a &'?x ()` -// with constraint `>::Ty == &'a &'?x ()` -struct WrapC(T); -impl<'a, 'x: 'a, T> Combine<'a> for WrapC -where - T: Combine<'a, Ty = &'a &'x ()>, -{ - type Ty = &'a &'x (); -} - -//==== Test implied bounds ====== - -fn test_wrap<'a, 'b, 'c1, 'c2, A, B>( - _: > as Combine<'a>>::Ty, // normalized: &'a A - _: > as Combine<'b>>::Ty, // normalized: &'b B - _: > as Combine<'c2>>::Ty, // normalized: &'c2 &'c1 () -) { - None::<&'a A>; - None::<&'b B>; - None::<&'c2 &'c1 ()>; -} - -fn main() {} From 8c4863b84179e2ff6075670dda9217d4594c1769 Mon Sep 17 00:00:00 2001 From: Robin Hafid Date: Tue, 14 Mar 2023 14:19:33 -0500 Subject: [PATCH 124/124] Rename 'src/bootstrap/native.rs' to llvm.rs Renamed 'native.rs' to 'llvm.rs', also moved `TestHelpers` to `test.rs`.Replaced all the `native.rs` ocurrences at `src/bootstrap` files to `llvm.rs` --- src/bootstrap/builder.rs | 14 ++--- src/bootstrap/compile.rs | 18 +++---- src/bootstrap/config.rs | 6 +-- src/bootstrap/config/tests.rs | 2 +- src/bootstrap/dist.rs | 12 ++--- src/bootstrap/download.rs | 2 +- src/bootstrap/lib.rs | 2 +- src/bootstrap/{native.rs => llvm.rs} | 65 ----------------------- src/bootstrap/test.rs | 79 +++++++++++++++++++++++++--- src/ci/stage-build.py | 2 +- 10 files changed, 101 insertions(+), 101 deletions(-) rename src/bootstrap/{native.rs => llvm.rs} (95%) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index bb07ca1908e1c..72d6713ccb3a4 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -16,7 +16,7 @@ use crate::config::{SplitDebuginfo, TargetSelection}; use crate::doc; use crate::flags::{Color, Subcommand}; use crate::install; -use crate::native; +use crate::llvm; use crate::run; use crate::setup; use crate::test; @@ -636,13 +636,13 @@ impl<'a> Builder<'a> { tool::Rustdoc, tool::Clippy, tool::CargoClippy, - native::Llvm, - native::Sanitizers, + llvm::Llvm, + llvm::Sanitizers, tool::Rustfmt, tool::Miri, tool::CargoMiri, - native::Lld, - native::CrtBeginEnd + llvm::Lld, + llvm::CrtBeginEnd ), Kind::Check | Kind::Clippy | Kind::Fix => describe!( check::Std, @@ -1101,7 +1101,7 @@ impl<'a> Builder<'a> { /// check build or dry-run, where there's no need to build all of LLVM. fn llvm_config(&self, target: TargetSelection) -> Option { if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run() { - let native::LlvmResult { llvm_config, .. } = self.ensure(native::Llvm { target }); + let llvm::LlvmResult { llvm_config, .. } = self.ensure(llvm::Llvm { target }); if llvm_config.is_file() { return Some(llvm_config); } @@ -1227,7 +1227,7 @@ impl<'a> Builder<'a> { // rustc_llvm. But if LLVM is stale, that'll be a tiny amount // of work comparatively, and we'd likely need to rebuild it anyway, // so that's okay. - if crate::native::prebuilt_llvm_config(self, target).is_err() { + if crate::llvm::prebuilt_llvm_config(self, target).is_err() { cargo.env("RUST_CHECK", "1"); } } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8b80dfc0f9b97..74aadbb5b5d23 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -24,7 +24,7 @@ use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::config::{LlvmLibunwind, RustcLto, TargetSelection}; use crate::dist; -use crate::native; +use crate::llvm; use crate::tool::SourceType; use crate::util::get_clang_cl_resource_dir; use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date}; @@ -191,7 +191,7 @@ fn copy_and_stamp( } fn copy_llvm_libunwind(builder: &Builder<'_>, target: TargetSelection, libdir: &Path) -> PathBuf { - let libunwind_path = builder.ensure(native::Libunwind { target }); + let libunwind_path = builder.ensure(llvm::Libunwind { target }); let libunwind_source = libunwind_path.join("libunwind.a"); let libunwind_target = libdir.join("libunwind.a"); builder.copy(&libunwind_source, &libunwind_target); @@ -266,7 +266,7 @@ fn copy_self_contained_objects( DependencyType::TargetSelfContained, ); } - let crt_path = builder.ensure(native::CrtBeginEnd { target }); + let crt_path = builder.ensure(llvm::CrtBeginEnd { target }); for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { let src = crt_path.join(obj); let target = libdir_self_contained.join(obj); @@ -468,7 +468,7 @@ fn copy_sanitizers( compiler: &Compiler, target: TargetSelection, ) -> Vec { - let runtimes: Vec = builder.ensure(native::Sanitizers { target }); + let runtimes: Vec = builder.ensure(llvm::Sanitizers { target }); if builder.config.dry_run() { return Vec::new(); @@ -870,12 +870,12 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS // busting caches (e.g. like #71152). if builder.config.llvm_enabled() && (builder.kind != Kind::Check - || crate::native::prebuilt_llvm_config(builder, target).is_ok()) + || crate::llvm::prebuilt_llvm_config(builder, target).is_ok()) { if builder.is_rust_llvm(target) { cargo.env("LLVM_RUSTLLVM", "1"); } - let native::LlvmResult { llvm_config, .. } = builder.ensure(native::Llvm { target }); + let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target }); cargo.env("LLVM_CONFIG", &llvm_config); if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { cargo.env("CFG_LLVM_ROOT", s); @@ -1353,7 +1353,7 @@ impl Step for Assemble { } let lld_install = if builder.config.lld_enabled { - Some(builder.ensure(native::Lld { target: target_compiler.host })) + Some(builder.ensure(llvm::Lld { target: target_compiler.host })) } else { None }; @@ -1417,8 +1417,8 @@ impl Step for Assemble { } if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) { - let native::LlvmResult { llvm_config, .. } = - builder.ensure(native::Llvm { target: target_compiler.host }); + let llvm::LlvmResult { llvm_config, .. } = + builder.ensure(llvm::Llvm { target: target_compiler.host }); if !builder.config.dry_run() { let llvm_bin_dir = output(Command::new(llvm_config).arg("--bindir")); let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 58729f396f0b6..ac4bf616c5a81 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -1193,11 +1193,11 @@ impl Config { 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, asserts) + crate::llvm::is_ci_llvm_available(&config, asserts) } Some(StringOrBool::Bool(b)) => b, None => { - config.channel == "dev" && crate::native::is_ci_llvm_available(&config, asserts) + config.channel == "dev" && crate::llvm::is_ci_llvm_available(&config, asserts) } }; @@ -1240,7 +1240,7 @@ impl Config { } } else { config.llvm_from_ci = - config.channel == "dev" && crate::native::is_ci_llvm_available(&config, false); + config.channel == "dev" && crate::llvm::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 index 16dc8c63abc96..5cea143e0a787 100644 --- a/src/bootstrap/config/tests.rs +++ b/src/bootstrap/config/tests.rs @@ -11,7 +11,7 @@ fn parse(config: &str) -> Config { #[test] fn download_ci_llvm() { - if crate::native::is_ci_llvm_modified(&parse("")) { + if crate::llvm::is_ci_llvm_modified(&parse("")) { eprintln!("Detected LLVM as non-available: running in CI and modified LLVM in this change"); return; } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index a3d9cb3e10c21..9f8584d4c2df6 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -27,7 +27,7 @@ use crate::channel; use crate::compile; use crate::config::TargetSelection; use crate::doc::DocumentationFormat; -use crate::native; +use crate::llvm; use crate::tarball::{GeneratedTarball, OverlayKind, Tarball}; use crate::tool::{self, Tool}; use crate::util::{exe, is_dylib, output, t, timeit}; @@ -1961,8 +1961,8 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir builder.install(&llvm_dylib_path, dst_libdir, 0o644); } !builder.config.dry_run() - } else if let Ok(native::LlvmResult { llvm_config, .. }) = - native::prebuilt_llvm_config(builder, target) + } else if let Ok(llvm::LlvmResult { llvm_config, .. }) = + llvm::prebuilt_llvm_config(builder, target) { let mut cmd = Command::new(llvm_config); cmd.arg("--libfiles"); @@ -2150,7 +2150,7 @@ impl Step for LlvmTools { } } - builder.ensure(crate::native::Llvm { target }); + builder.ensure(crate::llvm::Llvm { target }); let mut tarball = Tarball::new(builder, "llvm-tools", &target.triple); tarball.set_overlay(OverlayKind::LLVM); @@ -2209,10 +2209,10 @@ impl Step for RustDev { let mut tarball = Tarball::new(builder, "rust-dev", &target.triple); tarball.set_overlay(OverlayKind::LLVM); - builder.ensure(crate::native::Llvm { target }); + builder.ensure(crate::llvm::Llvm { target }); // We want to package `lld` to use it with `download-ci-llvm`. - builder.ensure(crate::native::Lld { target }); + builder.ensure(crate::llvm::Lld { target }); let src_bindir = builder.llvm_out(target).join("bin"); // If updating this list, you likely want to change diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index d1e2149d3f95f..8fbc034965a6c 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -12,7 +12,7 @@ use xz2::bufread::XzDecoder; use crate::{ config::RustfmtMetadata, - native::detect_llvm_sha, + llvm::detect_llvm_sha, t, util::{check_run, exe, program_out_of_date, try_run}, Config, diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index f136690592d72..39b07c672fffa 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -53,8 +53,8 @@ mod download; mod flags; mod format; mod install; +mod llvm; mod metadata; -mod native; mod run; mod sanity; mod setup; diff --git a/src/bootstrap/native.rs b/src/bootstrap/llvm.rs similarity index 95% rename from src/bootstrap/native.rs rename to src/bootstrap/llvm.rs index 41ee509655326..3d077556d959c 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/llvm.rs @@ -866,71 +866,6 @@ impl Step for Lld { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct TestHelpers { - pub target: TargetSelection, -} - -impl Step for TestHelpers { - type Output = (); - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("tests/auxiliary/rust_test_helpers.c") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(TestHelpers { target: run.target }) - } - - /// Compiles the `rust_test_helpers.c` library which we used in various - /// `run-pass` tests for ABI testing. - fn run(self, builder: &Builder<'_>) { - if builder.config.dry_run() { - return; - } - // The x86_64-fortanix-unknown-sgx target doesn't have a working C - // toolchain. However, some x86_64 ELF objects can be linked - // without issues. Use this hack to compile the test helpers. - let target = if self.target == "x86_64-fortanix-unknown-sgx" { - TargetSelection::from_user("x86_64-unknown-linux-gnu") - } else { - self.target - }; - let dst = builder.test_helpers_out(target); - let src = builder.src.join("tests/auxiliary/rust_test_helpers.c"); - if up_to_date(&src, &dst.join("librust_test_helpers.a")) { - return; - } - - builder.info("Building test helpers"); - t!(fs::create_dir_all(&dst)); - let mut cfg = cc::Build::new(); - // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 - if target.contains("emscripten") { - cfg.pic(false); - } - - // We may have found various cross-compilers a little differently due to our - // extra configuration, so inform cc of these compilers. Note, though, that - // on MSVC we still need cc's detection of env vars (ugh). - if !target.contains("msvc") { - if let Some(ar) = builder.ar(target) { - cfg.archiver(ar); - } - cfg.compiler(builder.cc(target)); - } - cfg.cargo_metadata(false) - .out_dir(&dst) - .target(&target.triple) - .host(&builder.config.build.triple) - .opt_level(0) - .warnings(false) - .debug(false) - .file(builder.src.join("tests/auxiliary/rust_test_helpers.c")) - .compile("rust_test_helpers"); - } -} - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Sanitizers { pub target: TargetSelection, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f5d680df1133b..b7dbb8444fd00 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -19,10 +19,10 @@ use crate::config::TargetSelection; use crate::dist; use crate::doc::DocumentationFormat; use crate::flags::Subcommand; -use crate::native; +use crate::llvm; use crate::tool::{self, SourceType, Tool}; use crate::toolstate::ToolState; -use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t}; +use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t, up_to_date}; use crate::{envify, CLang, DocTests, GitRepo, Mode}; const ADB_TEST_DIR: &str = "/data/local/tmp/work"; @@ -1430,11 +1430,11 @@ note: if you're sure you want to do this, please open an issue as to why. In the builder.ensure(compile::Std::new(compiler, compiler.host)); // Also provide `rust_test_helpers` for the host. - builder.ensure(native::TestHelpers { target: compiler.host }); + builder.ensure(TestHelpers { target: compiler.host }); // As well as the target, except for plain wasm32, which can't build it if !target.contains("wasm") || target.contains("emscripten") { - builder.ensure(native::TestHelpers { target }); + builder.ensure(TestHelpers { target }); } builder.ensure(RemoteCopyLibs { compiler, target }); @@ -1623,8 +1623,8 @@ note: if you're sure you want to do this, please open an issue as to why. In the let mut llvm_components_passed = false; let mut copts_passed = false; if builder.config.llvm_enabled() { - let native::LlvmResult { llvm_config, .. } = - builder.ensure(native::Llvm { target: builder.config.build }); + let llvm::LlvmResult { llvm_config, .. } = + builder.ensure(llvm::Llvm { target: builder.config.build }); if !builder.config.dry_run() { let llvm_version = output(Command::new(&llvm_config).arg("--version")); let llvm_components = output(Command::new(&llvm_config).arg("--components")); @@ -1662,7 +1662,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the // If LLD is available, add it to the PATH if builder.config.lld_enabled { let lld_install_root = - builder.ensure(native::Lld { target: builder.config.build }); + builder.ensure(llvm::Lld { target: builder.config.build }); let lld_bin_path = lld_install_root.join("bin"); @@ -2750,3 +2750,68 @@ impl Step for RustInstaller { run.builder.ensure(Self); } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct TestHelpers { + pub target: TargetSelection, +} + +impl Step for TestHelpers { + type Output = (); + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("tests/auxiliary/rust_test_helpers.c") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(TestHelpers { target: run.target }) + } + + /// Compiles the `rust_test_helpers.c` library which we used in various + /// `run-pass` tests for ABI testing. + fn run(self, builder: &Builder<'_>) { + if builder.config.dry_run() { + return; + } + // The x86_64-fortanix-unknown-sgx target doesn't have a working C + // toolchain. However, some x86_64 ELF objects can be linked + // without issues. Use this hack to compile the test helpers. + let target = if self.target == "x86_64-fortanix-unknown-sgx" { + TargetSelection::from_user("x86_64-unknown-linux-gnu") + } else { + self.target + }; + let dst = builder.test_helpers_out(target); + let src = builder.src.join("tests/auxiliary/rust_test_helpers.c"); + if up_to_date(&src, &dst.join("librust_test_helpers.a")) { + return; + } + + builder.info("Building test helpers"); + t!(fs::create_dir_all(&dst)); + let mut cfg = cc::Build::new(); + // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 + if target.contains("emscripten") { + cfg.pic(false); + } + + // We may have found various cross-compilers a little differently due to our + // extra configuration, so inform cc of these compilers. Note, though, that + // on MSVC we still need cc's detection of env vars (ugh). + if !target.contains("msvc") { + if let Some(ar) = builder.ar(target) { + cfg.archiver(ar); + } + cfg.compiler(builder.cc(target)); + } + cfg.cargo_metadata(false) + .out_dir(&dst) + .target(&target.triple) + .host(&builder.config.build.triple) + .opt_level(0) + .warnings(false) + .debug(false) + .file(builder.src.join("tests/auxiliary/rust_test_helpers.c")) + .compile("rust_test_helpers"); + } +} diff --git a/src/ci/stage-build.py b/src/ci/stage-build.py index fe3083dc31e46..8da128c8fe061 100644 --- a/src/ci/stage-build.py +++ b/src/ci/stage-build.py @@ -727,7 +727,7 @@ def record_metrics(pipeline: Pipeline, timer: Timer): metrics = load_last_metrics(pipeline.metrics_path()) if metrics is None: return - llvm_steps = tuple(metrics.find_all_by_type("bootstrap::native::Llvm")) + llvm_steps = tuple(metrics.find_all_by_type("bootstrap::llvm::Llvm")) assert len(llvm_steps) > 0 llvm_duration = sum(step.duration for step in llvm_steps)