From e960d0e751f0348726505a3d000023315259488e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 8 Oct 2023 12:21:58 +0000 Subject: [PATCH 01/41] Remove -Zdep-tasks. --- compiler/rustc_interface/src/tests.rs | 1 - .../rustc_query_system/src/dep_graph/graph.rs | 26 +++---------------- compiler/rustc_session/src/options.rs | 3 --- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2510ce7146022..60b9946f8266e 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -681,7 +681,6 @@ fn test_unstable_options_tracking_hash() { // tidy-alphabetical-start untracked!(assert_incr_state, Some(String::from("loaded"))); untracked!(deduplicate_diagnostics, false); - untracked!(dep_tasks, true); untracked!(dont_buffer_diagnostics, true); untracked!(dump_dep_graph, true); untracked!(dump_mir, Some(String::from("abc"))); diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index c7e92d7b2b227..a44000700cbfe 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -149,7 +149,6 @@ impl DepGraph { DepNode { kind: D::DEP_KIND_RED, hash: Fingerprint::ZERO.into() }, EdgesVec::new(), None, - false, ); assert_eq!(red_node_index, DepNodeIndex::FOREVER_RED_NODE); match red_node_prev_index_and_color { @@ -373,8 +372,6 @@ impl DepGraphData { let current_fingerprint = hash_result.map(|f| dcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, &result))); - let print_status = cfg!(debug_assertions) && dcx.sess().opts.unstable_opts.dep_tasks; - // Intern the new `DepNode`. let (dep_node_index, prev_and_color) = self.current.intern_node( dcx.profiler(), @@ -382,7 +379,6 @@ impl DepGraphData { key, edges, current_fingerprint, - print_status, ); hashing_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -589,8 +585,6 @@ impl DepGraph { cx.with_stable_hashing_context(|mut hcx| hash_result(&mut hcx, result)) }); - let print_status = cfg!(debug_assertions) && cx.sess().opts.unstable_opts.dep_tasks; - // Intern the new `DepNode` with the dependencies up-to-now. let (dep_node_index, prev_and_color) = data.current.intern_node( cx.profiler(), @@ -598,7 +592,6 @@ impl DepGraph { node, edges, current_fingerprint, - print_status, ); hashing_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -1219,20 +1212,13 @@ impl CurrentDepGraph { key: DepNode, edges: EdgesVec, fingerprint: Option, - print_status: bool, ) -> (DepNodeIndex, Option<(SerializedDepNodeIndex, DepNodeColor)>) { - let print_status = cfg!(debug_assertions) && print_status; - // Get timer for profiling `DepNode` interning let _node_intern_timer = self.node_intern_event_id.map(|eid| profiler.generic_activity_with_event_id(eid)); if let Some(prev_index) = prev_graph.node_to_index_opt(&key) { - let get_dep_node_index = |color, fingerprint| { - if print_status { - eprintln!("[task::{color:}] {key:?}"); - } - + let get_dep_node_index = |fingerprint| { let mut prev_index_to_index = self.prev_index_to_index.lock(); let dep_node_index = match prev_index_to_index[prev_index] { @@ -1256,12 +1242,12 @@ impl CurrentDepGraph { if fingerprint == prev_graph.fingerprint_by_index(prev_index) { // This is a green node: it existed in the previous compilation, // its query was re-executed, and it has the same result as before. - let dep_node_index = get_dep_node_index("green", fingerprint); + let dep_node_index = get_dep_node_index(fingerprint); (dep_node_index, Some((prev_index, DepNodeColor::Green(dep_node_index)))) } else { // This is a red node: it existed in the previous compilation, its query // was re-executed, but it has a different result from before. - let dep_node_index = get_dep_node_index("red", fingerprint); + let dep_node_index = get_dep_node_index(fingerprint); (dep_node_index, Some((prev_index, DepNodeColor::Red))) } } else { @@ -1269,14 +1255,10 @@ impl CurrentDepGraph { // session, its query was re-executed, but it doesn't compute a result hash // (i.e. it represents a `no_hash` query), so we have no way of determining // whether or not the result was the same as before. - let dep_node_index = get_dep_node_index("unknown", Fingerprint::ZERO); + let dep_node_index = get_dep_node_index(Fingerprint::ZERO); (dep_node_index, Some((prev_index, DepNodeColor::Red))) } } else { - if print_status { - eprintln!("[task::new] {key:?}"); - } - let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO); // This is a new node: it didn't exist in the previous compilation session. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c1424db600eff..5c9438ab9bd9b 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1452,9 +1452,6 @@ options! { dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], "in dep-info output, omit targets for tracking dependencies of the dep-info files \ themselves (default: no)"), - dep_tasks: bool = (false, parse_bool, [UNTRACKED], - "print tasks that execute and the color their dep node gets (requires debug build) \ - (default: no)"), dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED], "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \ (default: no)"), From 8531ebfc951a2002207bc5e604bc7584c1c1a560 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 8 Oct 2023 12:24:20 +0000 Subject: [PATCH 02/41] Remove useless debugging. --- compiler/rustc_query_impl/src/plumbing.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 4516708ce17c9..5bdf88aea1c53 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -437,8 +437,6 @@ where ); if let Some(key) = Q::Key::recover(tcx, &dep_node) { - #[cfg(debug_assertions)] - let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); force_query(query, QueryCtxt::new(tcx), key, dep_node); true } else { From 89f9da2056d88ab96faf95901687cb772d2dc10c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Tue, 10 Oct 2023 18:29:07 +0200 Subject: [PATCH 03/41] Bump stdarch submodule --- library/stdarch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/stdarch b/library/stdarch index 333e9e9977188..f4528dd6e85d9 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit 333e9e9977188d0748327e9b5be0f3f412063174 +Subproject commit f4528dd6e85d97bb802240d7cd048b6e1bf72540 From b57a1570920623d57c9e47b668896fe288d4f6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Tue, 10 Oct 2023 18:35:28 +0200 Subject: [PATCH 04/41] Remove from cranelift codegen LLVM intrinsics that are no longer needed --- .../src/intrinsics/llvm_x86.rs | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index 0c9a94e1c231f..559c64bb13bdd 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -32,41 +32,6 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ret.write_cvalue(fx, CValue::by_val(res, fx.layout_of(fx.tcx.types.i64))); } - // Used by `_mm_movemask_epi8` and `_mm256_movemask_epi8` - "llvm.x86.sse2.pmovmskb.128" - | "llvm.x86.avx2.pmovmskb" - | "llvm.x86.sse.movmsk.ps" - | "llvm.x86.sse2.movmsk.pd" => { - intrinsic_args!(fx, args => (a); intrinsic); - - let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx); - let lane_ty = fx.clif_type(lane_ty).unwrap(); - assert!(lane_count <= 32); - - let mut res = fx.bcx.ins().iconst(types::I32, 0); - - for lane in (0..lane_count).rev() { - let a_lane = a.value_lane(fx, lane).load_scalar(fx); - - // cast float to int - let a_lane = match lane_ty { - types::F32 => codegen_bitcast(fx, types::I32, a_lane), - types::F64 => codegen_bitcast(fx, types::I64, a_lane), - _ => a_lane, - }; - - // extract sign bit of an int - let a_lane_sign = fx.bcx.ins().ushr_imm(a_lane, i64::from(lane_ty.bits() - 1)); - - // shift sign bit into result - let a_lane_sign = clif_intcast(fx, a_lane_sign, types::I32, false); - res = fx.bcx.ins().ishl_imm(res, 1); - res = fx.bcx.ins().bor(res, a_lane_sign); - } - - let res = CValue::by_val(res, fx.layout_of(fx.tcx.types.i32)); - ret.write_cvalue(fx, res); - } "llvm.x86.sse.cmp.ps" | "llvm.x86.sse2.cmp.pd" => { let (x, y, kind) = match args { [x, y, kind] => (x, y, kind), From 337af7caf76e14051721943fb67484ad8a6cff35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Tue, 10 Oct 2023 18:43:42 +0200 Subject: [PATCH 05/41] Remove from miri LLVM intrinsics that are no longer needed --- src/tools/miri/src/shims/x86/sse.rs | 19 --- src/tools/miri/src/shims/x86/sse2.rs | 176 +-------------------------- src/tools/miri/src/shims/x86/sse3.rs | 26 ---- 3 files changed, 1 insertion(+), 220 deletions(-) diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index 6f0b76059f10d..831228b7a26cc 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -209,25 +209,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: )?; } } - // Used to implement the _mm_movemask_ps function. - // Returns a scalar integer where the i-th bit is the highest - // bit of the i-th component of `op`. - // https://www.felixcloutier.com/x86/movmskps - "movmsk.ps" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let (op, op_len) = this.operand_to_simd(op)?; - - let mut res = 0; - for i in 0..op_len { - let op = this.read_scalar(&this.project_index(&op, i)?)?; - let op = op.to_u32()?; - - // Extract the highest bit of `op` and place it in the `i`-th bit of `res` - res |= (op >> 31) << i; - } - - this.write_scalar(Scalar::from_u32(res), dest)?; - } _ => return Ok(EmulateForeignItemResult::NotSupported), } Ok(EmulateForeignItemResult::NeedsJumping) diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index c6a847b5cf824..3f2b9f5f0adfe 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -1,8 +1,4 @@ -use rustc_apfloat::{ - ieee::{Double, Single}, - Float as _, -}; -use rustc_middle::mir; +use rustc_apfloat::ieee::Double; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::Ty; use rustc_span::Symbol; @@ -39,49 +35,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: // Intrinsincs sufixed with "epiX" or "epuX" operate with X-bit signed or unsigned // vectors. match unprefixed_name { - // Used to implement the _mm_avg_epu8 and _mm_avg_epu16 functions. - // Averages packed unsigned 8/16-bit integers in `left` and `right`. - "pavg.b" | "pavg.w" => { - let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - for i in 0..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let right = this.read_immediate(&this.project_index(&right, i)?)?; - let dest = this.project_index(&dest, i)?; - - // Widen the operands to avoid overflow - let twice_wide = this.layout_of(this.get_twice_wide_int_ty(left.layout.ty))?; - let left = this.int_to_int_or_float(&left, twice_wide)?; - let right = this.int_to_int_or_float(&right, twice_wide)?; - - // Calculate left + right + 1 - let added = this.wrapping_binary_op(mir::BinOp::Add, &left, &right)?; - let added = this.wrapping_binary_op( - mir::BinOp::Add, - &added, - &ImmTy::from_uint(1u32, twice_wide), - )?; - - // Calculate (left + right + 1) / 2 - let divided = this.wrapping_binary_op( - mir::BinOp::Div, - &added, - &ImmTy::from_uint(2u32, twice_wide), - )?; - - // Narrow back to the original type - let res = this.int_to_int_or_float(÷d, dest.layout)?; - this.write_immediate(*res, &dest)?; - } - } // Used to implement the _mm_madd_epi16 function. // Multiplies packed signed 16-bit integers in `left` and `right`, producing // intermediate signed 32-bit integers. Horizontally add adjacent pairs of @@ -118,70 +71,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: this.write_scalar(Scalar::from_i32(res), &dest)?; } } - // Used to implement the _mm_mulhi_epi16 and _mm_mulhi_epu16 functions. - "pmulh.w" | "pmulhu.w" => { - let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - for i in 0..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let right = this.read_immediate(&this.project_index(&right, i)?)?; - let dest = this.project_index(&dest, i)?; - - // Widen the operands to avoid overflow - let twice_wide = this.layout_of(this.get_twice_wide_int_ty(left.layout.ty))?; - let left = this.int_to_int_or_float(&left, twice_wide)?; - let right = this.int_to_int_or_float(&right, twice_wide)?; - - // Multiply - let multiplied = this.wrapping_binary_op(mir::BinOp::Mul, &left, &right)?; - // Keep the high half - let high = this.wrapping_binary_op( - mir::BinOp::Shr, - &multiplied, - &ImmTy::from_uint(dest.layout.size.bits(), twice_wide), - )?; - - // Narrow back to the original type - let res = this.int_to_int_or_float(&high, dest.layout)?; - this.write_immediate(*res, &dest)?; - } - } - // Used to implement the _mm_mul_epu32 function. - // Multiplies the the low unsigned 32-bit integers from each packed - // 64-bit element and stores the result as 64-bit unsigned integers. - "pmulu.dq" => { - let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - // left and right are u32x4, dest is u64x2 - assert_eq!(left_len, 4); - assert_eq!(right_len, 4); - assert_eq!(dest_len, 2); - - for i in 0..dest_len { - let op_i = i.checked_mul(2).unwrap(); - let left = this.read_scalar(&this.project_index(&left, op_i)?)?.to_u32()?; - let right = this.read_scalar(&this.project_index(&right, op_i)?)?.to_u32()?; - let dest = this.project_index(&dest, i)?; - - // The multiplication will not overflow because stripping the - // operands are expanded from 32-bit to 64-bit. - let res = u64::from(left).checked_mul(u64::from(right)).unwrap(); - this.write_scalar(Scalar::from_u64(res), &dest)?; - } - } // Used to implement the _mm_sad_epu8 function. // Computes the absolute differences of packed unsigned 8-bit integers in `a` // and `b`, then horizontally sum each consecutive 8 differences to produce @@ -370,25 +259,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: this.write_scalar(Scalar::from_u64(res), &dest)?; } } - // Used to implement the _mm_cvtepi32_ps function. - // Converts packed i32 to packed f32. - // FIXME: Can we get rid of this intrinsic and just use simd_as? - "cvtdq2ps" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (op, op_len) = this.operand_to_simd(op)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, op_len); - - for i in 0..dest_len { - let op = this.read_scalar(&this.project_index(&op, i)?)?.to_i32()?; - let dest = this.project_index(&dest, i)?; - - let res = Scalar::from_f32(Single::from_i128(op.into()).value); - this.write_scalar(res, &dest)?; - } - } // Used to implement the _mm_cvtps_epi32 and _mm_cvttps_epi32 functions. // Converts packed f32 to packed i32. "cvtps2dq" | "cvttps2dq" => { @@ -652,31 +522,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: }; this.write_scalar(Scalar::from_i32(i32::from(res)), dest)?; } - // Used to implement the _mm_cvtpd_ps and _mm_cvtps_pd functions. - // Converts packed f32/f64 to packed f64/f32. - "cvtpd2ps" | "cvtps2pd" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (op, op_len) = this.operand_to_simd(op)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - // For cvtpd2ps: op is f64x2, dest is f32x4 - // For cvtps2pd: op is f32x4, dest is f64x2 - // In either case, the two first values are converted - for i in 0..op_len.min(dest_len) { - let op = this.read_immediate(&this.project_index(&op, i)?)?; - let dest = this.project_index(&dest, i)?; - - let res = this.float_to_float_or_int(&op, dest.layout)?; - this.write_immediate(*res, &dest)?; - } - // For f32 -> f64, ignore the remaining - // For f64 -> f32, fill the remaining with zeros - for i in op_len..dest_len { - let dest = this.project_index(&dest, i)?; - this.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?; - } - } // Used to implement the _mm_cvtpd_epi32 and _mm_cvttpd_epi32 functions. // Converts packed f64 to packed i32. "cvtpd2dq" | "cvttpd2dq" => { @@ -772,25 +617,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: )?; } } - // Used to implement the _mm_movemask_pd function. - // Returns a scalar integer where the i-th bit is the highest - // bit of the i-th component of `op`. - // https://www.felixcloutier.com/x86/movmskpd - "movmsk.pd" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let (op, op_len) = this.operand_to_simd(op)?; - - let mut res = 0; - for i in 0..op_len { - let op = this.read_scalar(&this.project_index(&op, i)?)?; - let op = op.to_u64()?; - - // Extract the highest bit of `op` and place it in the `i`-th bit of `res` - res |= (op >> 63) << i; - } - - this.write_scalar(Scalar::from_u32(res.try_into().unwrap()), dest)?; - } // Used to implement the `_mm_pause` function. // The intrinsic is used to hint the processor that the code is in a spin-loop. "pause" => { diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs index a41de5dbf7ee5..20a4b560749ac 100644 --- a/src/tools/miri/src/shims/x86/sse3.rs +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -23,32 +23,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse3.").unwrap(); match unprefixed_name { - // Used to implement the _mm_addsub_ps and _mm_addsub_pd functions. - // Alternatingly add and subtract floating point (f32 or f64) from - // `left` and `right` - "addsub.ps" | "addsub.pd" => { - let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - for i in 0..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let right = this.read_immediate(&this.project_index(&right, i)?)?; - let dest = this.project_index(&dest, i)?; - - // Even elements are subtracted and odd elements are added. - let op = if i % 2 == 0 { mir::BinOp::Sub } else { mir::BinOp::Add }; - let res = this.wrapping_binary_op(op, &left, &right)?; - - this.write_immediate(*res, &dest)?; - } - } // Used to implement the _mm_h{add,sub}_p{s,d} functions. // Horizontally add/subtract adjacent floating point values // in `left` and `right`. From 35e2f4e0af4bfce8802239ac498255ee9b02fbb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Tue, 10 Oct 2023 18:44:53 +0200 Subject: [PATCH 06/41] Fix identation of a `rustfmt::skip`ed statement --- src/tools/miri/tests/pass/intrinsics-x86-sse2.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs b/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs index 2c7665bc73631..e636d6c8aaf8d 100644 --- a/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs +++ b/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs @@ -117,12 +117,12 @@ mod tests { #[target_feature(enable = "sse2")] unsafe fn test_mm_sad_epu8() { #[rustfmt::skip] - let a = _mm_setr_epi8( - 255u8 as i8, 254u8 as i8, 253u8 as i8, 252u8 as i8, - 1, 2, 3, 4, - 155u8 as i8, 154u8 as i8, 153u8 as i8, 152u8 as i8, - 1, 2, 3, 4, - ); + let a = _mm_setr_epi8( + 255u8 as i8, 254u8 as i8, 253u8 as i8, 252u8 as i8, + 1, 2, 3, 4, + 155u8 as i8, 154u8 as i8, 153u8 as i8, 152u8 as i8, + 1, 2, 3, 4, + ); let b = _mm_setr_epi8(0, 0, 0, 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2); let r = _mm_sad_epu8(a, b); let e = _mm_setr_epi64x(1020, 614); From 991bf752f1bbd0863864a978fee1236a93499464 Mon Sep 17 00:00:00 2001 From: Milo <50248166+Milo123459@users.noreply.github.com> Date: Sat, 14 Oct 2023 18:49:51 +0000 Subject: [PATCH 07/41] make E0277 use short paths add note change wording short_ty_string on t --- .../traits/error_reporting/type_err_ctxt_ext.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 8adfb27a3f448..f83ee576c2941 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -429,14 +429,18 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { return; } let trait_ref = trait_predicate.to_poly_trait_ref(); - - let (post_message, pre_message, type_def) = self + let (post_message, pre_message, type_def, file_note) = self .get_parent_trait_ref(obligation.cause.code()) .map(|(t, s)| { + let (t, file) = self.tcx.short_ty_string(t); ( format!(" in `{t}`"), format!("within `{t}`, "), s.map(|s| (format!("within this `{t}`"), s)), + file.and_then(|file| Some(format!( + "the full trait has been written to '{}'", + file.display(), + ))) ) }) .unwrap_or_default(); @@ -544,6 +548,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.emit(); return; } + + file_note.map(|note| err.note(note)); if let Some(s) = label { // If it has a custom `#[rustc_on_unimplemented]` // error message, let's display it as the label! @@ -1077,7 +1083,7 @@ pub(super) trait InferCtxtPrivExt<'tcx> { fn get_parent_trait_ref( &self, code: &ObligationCauseCode<'tcx>, - ) -> Option<(String, Option)>; + ) -> Option<(Ty<'tcx>, Option)>; /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait /// with the same path as `trait_ref`, a help message about @@ -1927,7 +1933,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { fn get_parent_trait_ref( &self, code: &ObligationCauseCode<'tcx>, - ) -> Option<(String, Option)> { + ) -> Option<(Ty<'tcx>, Option)> { match code { ObligationCauseCode::BuiltinDerivedObligation(data) => { let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); @@ -1937,7 +1943,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let ty = parent_trait_ref.skip_binder().self_ty(); let span = TyCategory::from_ty(self.tcx, ty) .map(|(_, def_id)| self.tcx.def_span(def_id)); - Some((ty.to_string(), span)) + Some((ty, span)) } } } From 62fe807e3c6cec9ae31a0a3e7e1f5bc694c2e30c Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:10:30 -0700 Subject: [PATCH 08/41] FileCheck asm_unwind --- tests/mir-opt/inline/asm_unwind.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/asm_unwind.rs b/tests/mir-opt/inline/asm_unwind.rs index 0cf21fda72fac..596a4592f25ff 100644 --- a/tests/mir-opt/inline/asm_unwind.rs +++ b/tests/mir-opt/inline/asm_unwind.rs @@ -1,4 +1,3 @@ -// skip-filecheck // Tests inlining of `may_unwind` inline assembly. // // EMIT_MIR_FOR_EACH_PANIC_STRATEGY @@ -20,5 +19,7 @@ fn foo() { // EMIT_MIR asm_unwind.main.Inline.diff pub fn main() { + // CHECK-LABEL: fn main( + // CHECK: (inlined foo) foo(); } From 2d0a34bb78f5546a0a7d7b447ffe4fa1c1ea13d9 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:11:06 -0700 Subject: [PATCH 09/41] FileCheck caller_with_trivial_bound --- tests/mir-opt/inline/caller_with_trivial_bound.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/caller_with_trivial_bound.rs b/tests/mir-opt/inline/caller_with_trivial_bound.rs index 3829cbdd30240..722c7f6724efd 100644 --- a/tests/mir-opt/inline/caller_with_trivial_bound.rs +++ b/tests/mir-opt/inline/caller_with_trivial_bound.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // needs-unwind @@ -18,6 +17,8 @@ pub fn foo() where IntFactory: Factory, { + // CHECK-LABEL: fn foo( + // CHECK-NOT: (inlined bar::) let mut x: >::Item = bar::(); } From 2f9aa7da9fefdd028d09e4c7450994b3323b2cfa Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:11:22 -0700 Subject: [PATCH 10/41] FileCheck cycle --- tests/mir-opt/inline/cycle.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/cycle.rs b/tests/mir-opt/inline/cycle.rs index 3e4f06834358e..8716b44b3dc02 100644 --- a/tests/mir-opt/inline/cycle.rs +++ b/tests/mir-opt/inline/cycle.rs @@ -1,20 +1,27 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Zinline-mir-hint-threshold=1000 // EMIT_MIR cycle.f.Inline.diff #[inline(always)] fn f(g: impl Fn()) { + // CHECK-LABEL: fn f( + // CHECK-NOT: inlined g(); } // EMIT_MIR cycle.g.Inline.diff #[inline(always)] fn g() { + // CHECK-LABEL: fn g( + // CHECK: (inlined f::) + // CHECK-NOT: inlined f(main); } // EMIT_MIR cycle.main.Inline.diff fn main() { + // CHECK-LABEL: fn main( + // CHECK: (inlined f::) + // CHECK-NOT: inlined f(g); } From 9b3f5e15277a2089140db89704277a682374efba Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:11:37 -0700 Subject: [PATCH 11/41] FileCheck dont_ice_on_generic_rust_call --- tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs index 4147325ec44b9..3307a1408fb56 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Zmir-enable-passes=+Inline --crate-type=lib @@ -8,5 +7,7 @@ use std::marker::Tuple; // EMIT_MIR dont_ice_on_generic_rust_call.call.Inline.diff pub fn call(mut mock: Box>, input: I) { + // CHECK-LABEL: fn call( + // CHECK-NOT: (inlined > as FnMut>::call_mut) mock.call_mut(input) } From 76faae9cdcf0d37884809ab0d21689fbc7598b98 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:11:50 -0700 Subject: [PATCH 12/41] FileCheck dyn_trait --- tests/mir-opt/inline/dyn_trait.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/dyn_trait.rs b/tests/mir-opt/inline/dyn_trait.rs index 7b41b1e1171e2..005cf155fdb93 100644 --- a/tests/mir-opt/inline/dyn_trait.rs +++ b/tests/mir-opt/inline/dyn_trait.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] @@ -20,18 +19,26 @@ pub trait Query { // EMIT_MIR dyn_trait.mk_cycle.Inline.diff #[inline(always)] pub fn mk_cycle(c: &dyn Cache) { + // CHECK-LABEL: fn mk_cycle( + // CHECK-NOT: (inlined as Cache>::store_nocache) c.store_nocache() } // EMIT_MIR dyn_trait.try_execute_query.Inline.diff #[inline(always)] pub fn try_execute_query(c: &C) { + // CHECK-LABEL: fn try_execute_query( + // CHECK: (inlined mk_cycle::<::V>) mk_cycle(c) } // EMIT_MIR dyn_trait.get_query.Inline.diff #[inline(always)] pub fn get_query(t: &T) { + // CHECK-LABEL: fn get_query( + // CHECK-NOT: (inlined ::cache::) let c = Q::cache(t); + // CHECK: (inlined try_execute_query::<::C>) + // CHECK: (inlined mk_cycle::<::V>) try_execute_query(c) } From f005d2325a5b838a4015b0233ee022c455962801 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:12:05 -0700 Subject: [PATCH 13/41] FileCheck exponential_runtime --- tests/mir-opt/inline/exponential_runtime.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/exponential_runtime.rs b/tests/mir-opt/inline/exponential_runtime.rs index 6d3af8b9c572a..499bec33ffc9b 100644 --- a/tests/mir-opt/inline/exponential_runtime.rs +++ b/tests/mir-opt/inline/exponential_runtime.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Checks that code with exponential runtime does not have exponential behavior in inlining. @@ -85,5 +84,13 @@ impl A for () { // EMIT_MIR exponential_runtime.main.Inline.diff fn main() { + // CHECK-LABEL: fn main( + // CHECK: (inlined <() as G>::call) + // CHECK: (inlined <() as F>::call) + // CHECK: (inlined <() as E>::call) + // CHECK: (inlined <() as D>::call) + // CHECK: (inlined <() as C>::call) + // CHECK: (inlined <() as B>::call) + // CHECK-NOT: inlined <() as G>::call(); } From 22679cd36df7ad05eaea153b64712e97ffe69ecf Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:12:17 -0700 Subject: [PATCH 14/41] FileCheck inline_any_operand --- tests/mir-opt/inline/inline_any_operand.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_any_operand.rs b/tests/mir-opt/inline/inline_any_operand.rs index e131cd6ef7ee8..659b7c3a0a1f5 100644 --- a/tests/mir-opt/inline/inline_any_operand.rs +++ b/tests/mir-opt/inline/inline_any_operand.rs @@ -1,4 +1,3 @@ -// skip-filecheck // compile-flags: -Z span_free_formats // Tests that MIR inliner works for any operand @@ -9,6 +8,8 @@ fn main() { // EMIT_MIR inline_any_operand.bar.Inline.after.mir fn bar() -> bool { + // CHECK-LABEL: fn bar( + // CHECK: (inlined foo) let f = foo; f(1, -1) } From de56d2d9b2c501985b5f30eb6506475bf312c0c0 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:24:38 -0700 Subject: [PATCH 15/41] FileCheck inline_box_fn --- tests/mir-opt/inline/inline_box_fn.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_box_fn.rs b/tests/mir-opt/inline/inline_box_fn.rs index f6a90b92c9118..7686477c291a3 100644 --- a/tests/mir-opt/inline/inline_box_fn.rs +++ b/tests/mir-opt/inline/inline_box_fn.rs @@ -1,9 +1,10 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: Inline // compile-flags: --crate-type=lib // EMIT_MIR inline_box_fn.call.Inline.diff fn call(x: Box) { + // CHECK-LABEL: fn call( + // CHECK-NOT: (inlined as Fn<(i32,)>>::call) x(1); } From 9d61e6a4e46899a00da5908cf6db34a7d2bebb28 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:28:38 -0700 Subject: [PATCH 16/41] FileCheck inline_closure_borrows_arg --- tests/mir-opt/inline/inline_closure_borrows_arg.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_closure_borrows_arg.rs b/tests/mir-opt/inline/inline_closure_borrows_arg.rs index a5cc7d1036530..1570ab057c728 100644 --- a/tests/mir-opt/inline/inline_closure_borrows_arg.rs +++ b/tests/mir-opt/inline/inline_closure_borrows_arg.rs @@ -1,4 +1,3 @@ -// skip-filecheck // compile-flags: -Z span_free_formats -Zunsound-mir-opts // Tests that MIR inliner can handle closure arguments, @@ -14,5 +13,8 @@ fn foo(_t: T, q: &i32) -> i32 { let variable = &*r; *variable }; + + // CHECK-LABEL: fn foo( + // CHECK: (inlined foo::::{closure#0}) x(q, q) } From 5caee416a5c53c997c35d2358cb61e2499a1e263 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:30:04 -0700 Subject: [PATCH 17/41] FileCheck inline_closure_captures --- tests/mir-opt/inline/inline_closure_captures.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_closure_captures.rs b/tests/mir-opt/inline/inline_closure_captures.rs index 0d95564e5ddee..2b08b10688728 100644 --- a/tests/mir-opt/inline/inline_closure_captures.rs +++ b/tests/mir-opt/inline/inline_closure_captures.rs @@ -1,4 +1,3 @@ -// skip-filecheck // compile-flags: -Z span_free_formats // Tests that MIR inliner can handle closure captures. @@ -10,5 +9,8 @@ fn main() { // EMIT_MIR inline_closure_captures.foo.Inline.after.mir fn foo(t: T, q: i32) -> (i32, T) { let x = |_q| (q, t); + + // CHECK-LABEL: fn foo( + // CHECK: (inlined foo::::{closure#0}) x(q) } From 7ee05d24b5103df74d93c267ab4e1d8060aec444 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 11:31:05 -0700 Subject: [PATCH 18/41] FileCheck inline_closure --- tests/mir-opt/inline/inline_closure.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_closure.rs b/tests/mir-opt/inline/inline_closure.rs index bd4c84ff0ca29..65f55d49a806e 100644 --- a/tests/mir-opt/inline/inline_closure.rs +++ b/tests/mir-opt/inline/inline_closure.rs @@ -1,4 +1,3 @@ -// skip-filecheck // compile-flags: -Z span_free_formats // Tests that MIR inliner can handle closure arguments. (#45894) @@ -10,5 +9,8 @@ fn main() { // EMIT_MIR inline_closure.foo.Inline.after.mir fn foo(_t: T, q: i32) -> i32 { let x = |_t, _q| _t; + + // CHECK-LABEL: fn foo( + // CHECK: (inlined foo::::{closure#0}) x(q, q) } From d8f33ef93d6dbff4267fd7d779d73a76f1e46e28 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 18:03:13 -0700 Subject: [PATCH 19/41] FileCheck inline_diverging --- tests/mir-opt/inline/inline_diverging.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_diverging.rs b/tests/mir-opt/inline/inline_diverging.rs index 9e50b1ead2bc0..25a5b9c5c5e72 100644 --- a/tests/mir-opt/inline/inline_diverging.rs +++ b/tests/mir-opt/inline/inline_diverging.rs @@ -1,4 +1,3 @@ -// skip-filecheck // Tests inlining of diverging calls. // // EMIT_MIR_FOR_EACH_PANIC_STRATEGY @@ -7,6 +6,8 @@ // EMIT_MIR inline_diverging.f.Inline.diff pub fn f() { + // CHECK-LABEL: fn f( + // CHECK: (inlined sleep) sleep(); } @@ -15,12 +16,17 @@ pub fn g(i: i32) -> u32 { if i > 0 { i as u32 } else { + // CHECK-LABEL: fn g( + // CHECK: (inlined panic) panic(); } } // EMIT_MIR inline_diverging.h.Inline.diff pub fn h() { + // CHECK-LABEL: fn h( + // CHECK: (inlined call_twice:: ! {sleep}>) + // CHECK-NOT: inlined call_twice(sleep); } From 20e7caa737b1ee4ae34a89201ebc972a4d495982 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 18:15:32 -0700 Subject: [PATCH 20/41] FileCheck inline_coroutine --- ...ne_coroutine.main.Inline.panic-unwind.diff | 22 +++++++++---------- tests/mir-opt/inline/inline_coroutine.rs | 4 +++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff index e7d020968389f..fdb42bf3d8a0e 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff @@ -4,26 +4,26 @@ fn main() -> () { let mut _0: (); let _1: std::ops::CoroutineState; - let mut _2: std::pin::Pin<&mut {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8}>; - let mut _3: &mut {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8}; - let mut _4: {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8}; + let mut _2: std::pin::Pin<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>; + let mut _3: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}; + let mut _4: {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}; + let mut _5: bool; scope 1 { debug _r => _1; } + scope 2 (inlined g) { + } -+ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8}>::new) { ++ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new) { + debug pointer => _3; + scope 4 { -+ scope 5 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8}>::new_unchecked) { ++ scope 5 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) { + debug pointer => _3; + } + } + } + scope 6 (inlined g::{closure#0}) { + debug a => _5; -+ let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8}; ++ let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}; + let mut _7: u32; + let mut _8: i32; + } @@ -37,20 +37,20 @@ - } - - bb1: { -+ _4 = {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8 (#0)}; ++ _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)}; _3 = &mut _4; -- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8}>::new(move _3) -> [return: bb2, unwind: bb5]; +- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind: bb5]; - } - - bb2: { -+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8}> { pointer: move _3 }; ++ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: move _3 }; StorageDead(_3); -- _1 = <{coroutine@$DIR/inline_coroutine.rs:17:5: 17:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind: bb5]; +- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind: bb5]; + StorageLive(_5); + _5 = const false; + StorageLive(_6); + StorageLive(_7); -+ _6 = (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:17:5: 17:8}); ++ _6 = (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}); + _7 = discriminant((*_6)); + switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11]; } diff --git a/tests/mir-opt/inline/inline_coroutine.rs b/tests/mir-opt/inline/inline_coroutine.rs index d021cdac28efa..a82586bf2bfac 100644 --- a/tests/mir-opt/inline/inline_coroutine.rs +++ b/tests/mir-opt/inline/inline_coroutine.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Zinline-mir-hint-threshold=1000 #![feature(coroutines, coroutine_trait)] @@ -8,6 +7,9 @@ use std::pin::Pin; // EMIT_MIR inline_coroutine.main.Inline.diff fn main() { + // CHECK-LABEL: fn main( + // CHECK: (inlined g) + // CHECK: (inlined g::{closure#0}) let _r = Pin::new(&mut g()).resume(false); } From 19c36a96dfce27de7ad60f084e4bbc9abfdf4768 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 18:21:41 -0700 Subject: [PATCH 21/41] FileCheck inline_instruction_set --- tests/mir-opt/inline/inline_instruction_set.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_instruction_set.rs b/tests/mir-opt/inline/inline_instruction_set.rs index 4ac4d462f82de..7cb59645587b6 100644 --- a/tests/mir-opt/inline/inline_instruction_set.rs +++ b/tests/mir-opt/inline/inline_instruction_set.rs @@ -1,4 +1,3 @@ -// skip-filecheck // Checks that only functions with the compatible instruction_set attributes are inlined. // // A function is "compatible" when the *callee* has the same attribute or no attribute. @@ -47,16 +46,26 @@ fn inline_always_and_using_inline_asm() { // EMIT_MIR inline_instruction_set.t32.Inline.diff #[instruction_set(arm::t32)] pub fn t32() { + // CHECK-LABEL: fn t32( + // CHECK-NOT: (inlined instruction_set_a32) instruction_set_a32(); + // CHECK: (inlined instruction_set_t32) instruction_set_t32(); + // CHECK: (inlined instruction_set_default) instruction_set_default(); + // CHECK-NOT: (inlined inline_always_and_using_inline_asm) inline_always_and_using_inline_asm(); } // EMIT_MIR inline_instruction_set.default.Inline.diff pub fn default() { + // CHECK-LABEL: fn default( + // CHECK-NOT: (inlined instruction_set_a32) instruction_set_a32(); + // CHECK-NOT: (inlined instruction_set_t32) instruction_set_t32(); + // CHECK: (inlined instruction_set_default) instruction_set_default(); + // CHECK: (inlined inline_always_and_using_inline_asm) inline_always_and_using_inline_asm(); } From de8255194a292d59c14b4d4a4424e576c7820373 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 20:33:22 -0700 Subject: [PATCH 22/41] FileCheck inline_into_box_place --- tests/mir-opt/inline/inline_into_box_place.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_into_box_place.rs b/tests/mir-opt/inline/inline_into_box_place.rs index b755692afc214..65f8e2916b630 100644 --- a/tests/mir-opt/inline/inline_into_box_place.rs +++ b/tests/mir-opt/inline/inline_into_box_place.rs @@ -1,4 +1,3 @@ -// skip-filecheck // ignore-endian-big // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // ignore-debug MIR alignment checks in std alter the diff, breaking the test @@ -6,5 +5,7 @@ // EMIT_MIR inline_into_box_place.main.Inline.diff fn main() { + // CHECK-LABEL: fn main( + // CHECK: (inlined Box::>::new) let _x: Box> = Box::new(Vec::new()); } From 3202d4e35761cc73b70465fa55f414840728e83a Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 20:34:41 -0700 Subject: [PATCH 23/41] FileCheck inline_options --- tests/mir-opt/inline/inline_options.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_options.rs b/tests/mir-opt/inline/inline_options.rs index 394a8c4945cdd..b940c64f0b886 100644 --- a/tests/mir-opt/inline/inline_options.rs +++ b/tests/mir-opt/inline/inline_options.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Checks that inlining threshold can be controlled with // inline-mir-threshold and inline-hint-threshold options. @@ -8,7 +7,10 @@ // EMIT_MIR inline_options.main.Inline.after.mir fn main() { + // CHECK-LABEL: fn main( + // CHECK-NOT: (inlined not_inlined) not_inlined(); + // CHECK: (inlined inlined::) inlined::(); } From 21a4c39cb849d32c1209329a740e2c3013ebe063 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 20:38:15 -0700 Subject: [PATCH 24/41] FileCheck inline_retag --- tests/mir-opt/inline/inline_retag.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_retag.rs b/tests/mir-opt/inline/inline_retag.rs index f695b9f22e616..c90c0b819b7ba 100644 --- a/tests/mir-opt/inline/inline_retag.rs +++ b/tests/mir-opt/inline/inline_retag.rs @@ -1,4 +1,3 @@ -// skip-filecheck // compile-flags: -Z span_free_formats -Z mir-emit-retag // Tests that MIR inliner fixes up `Retag`'s `fn_entry` flag @@ -9,6 +8,8 @@ fn main() { // EMIT_MIR inline_retag.bar.Inline.after.mir fn bar() -> bool { + // CHECK-LABEL: fn bar( + // CHECK: (inlined foo) let f = foo; f(&1, &-1) } From 25325667f2be173d0d8968f053e20d36ed24545b Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 20:40:20 -0700 Subject: [PATCH 25/41] FileCheck inline_specialization --- tests/mir-opt/inline/inline_specialization.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_specialization.rs b/tests/mir-opt/inline/inline_specialization.rs index eb0cf891dad01..6453abc008129 100644 --- a/tests/mir-opt/inline/inline_specialization.rs +++ b/tests/mir-opt/inline/inline_specialization.rs @@ -1,9 +1,10 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![feature(specialization)] // EMIT_MIR inline_specialization.main.Inline.diff fn main() { + // CHECK-LABEL: fn main( + // CHECK: (inlined as Foo>::bar) let x = as Foo>::bar(); } From f7acf17945b6a5739fc498330c698579982fbaf8 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 20:41:43 -0700 Subject: [PATCH 26/41] FileCheck inline_trait_method_2 --- tests/mir-opt/inline/inline_trait_method_2.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_trait_method_2.rs b/tests/mir-opt/inline/inline_trait_method_2.rs index e87609a8c7e00..b0b6a7b9b01de 100644 --- a/tests/mir-opt/inline/inline_trait_method_2.rs +++ b/tests/mir-opt/inline/inline_trait_method_2.rs @@ -1,9 +1,11 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Z span_free_formats -Z mir-opt-level=4 // EMIT_MIR inline_trait_method_2.test2.Inline.after.mir fn test2(x: &dyn X) -> bool { + // CHECK-LABEL: fn test2( + // CHECK: (inlined test) + // CHECK-NOT: (inlined ::y) test(x) } From 1b9cb5d59bb704c8a7920abcdbdef83f3273afba Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 21:32:56 -0700 Subject: [PATCH 27/41] FileCheck inline_trait_method --- tests/mir-opt/inline/inline_trait_method.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/inline_trait_method.rs b/tests/mir-opt/inline/inline_trait_method.rs index 8a95adf3713e2..ea09966a2aa94 100644 --- a/tests/mir-opt/inline/inline_trait_method.rs +++ b/tests/mir-opt/inline/inline_trait_method.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Z span_free_formats @@ -8,6 +7,8 @@ fn main() { // EMIT_MIR inline_trait_method.test.Inline.after.mir fn test(x: &dyn X) -> u32 { + // CHECK-LABEL: fn test( + // CHECK-NOT: (inlined ::y) x.y() } From 773dc6275666afc56d2ef442f07e2b3908c692d3 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 21:41:07 -0700 Subject: [PATCH 28/41] FileCheck inline_as_ref_as_mut --- tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs index da779fed76fb5..4517c88d71340 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs @@ -1,21 +1,28 @@ -// skip-filecheck // EMIT_MIR issue_58867_inline_as_ref_as_mut.a.Inline.after.mir pub fn a(x: &mut [T]) -> &mut [T] { + // CHECK-LABEL: fn a( + // CHECK: (inlined <[T] as AsMut<[T]>>::as_mut) x.as_mut() } // EMIT_MIR issue_58867_inline_as_ref_as_mut.b.Inline.after.mir pub fn b(x: &mut Box) -> &mut T { + // CHECK-LABEL: fn b( + // CHECK: (inlined as AsMut>::as_mut) x.as_mut() } // EMIT_MIR issue_58867_inline_as_ref_as_mut.c.Inline.after.mir pub fn c(x: &[T]) -> &[T] { + // CHECK-LABEL: fn c( + // CHECK: (inlined <[T] as AsRef<[T]>>::as_ref) x.as_ref() } // EMIT_MIR issue_58867_inline_as_ref_as_mut.d.Inline.after.mir pub fn d(x: &Box) -> &T { + // CHECK-LABEL: fn d( + // CHECK: (inlined as AsRef>::as_ref) x.as_ref() } From bb695977de920f47eb87ccf7580bb04a6bd36350 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 21:57:08 -0700 Subject: [PATCH 29/41] FileCheck inline_scopes_parenting --- ...ssue_76997_inline_scopes_parenting.main.Inline.after.mir | 6 +++--- tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir index d28c0441f63c3..ba5eb757cf977 100644 --- a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir +++ b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir @@ -2,8 +2,8 @@ fn main() -> () { let mut _0: (); - let _1: {closure@$DIR/issue_76997_inline_scopes_parenting.rs:6:13: 6:16}; - let mut _2: &{closure@$DIR/issue_76997_inline_scopes_parenting.rs:6:13: 6:16}; + let _1: {closure@$DIR/issue_76997_inline_scopes_parenting.rs:10:13: 10:16}; + let mut _2: &{closure@$DIR/issue_76997_inline_scopes_parenting.rs:10:13: 10:16}; let mut _3: ((),); let mut _4: (); let mut _5: (); @@ -19,7 +19,7 @@ fn main() -> () { bb0: { StorageLive(_1); - _1 = {closure@$DIR/issue_76997_inline_scopes_parenting.rs:6:13: 6:16}; + _1 = {closure@$DIR/issue_76997_inline_scopes_parenting.rs:10:13: 10:16}; StorageLive(_2); _2 = &_1; StorageLive(_3); diff --git a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs index c7147d42df996..2a7c931a659ee 100644 --- a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs +++ b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs @@ -1,8 +1,12 @@ -// skip-filecheck // Tests that MIR inliner can handle `SourceScopeData` parenting correctly. (#76997) // EMIT_MIR issue_76997_inline_scopes_parenting.main.Inline.after.mir fn main() { + // CHECK-LABEL: fn main( + // CHECK: scope 2 + // CHECK-NEXT: debug x + // CHECK-NEXT: scope 3 + // CHECK-NEXT: debug y let f = |x| { let y = x; y }; f(()) } From 5cf65eb16a57469212a682d469829c082ec25fb2 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 22:06:38 -0700 Subject: [PATCH 30/41] FileCheck issue_78442 --- tests/mir-opt/inline/issue_78442.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/issue_78442.rs b/tests/mir-opt/inline/issue_78442.rs index f83ed70d0db32..f9a5234283a03 100644 --- a/tests/mir-opt/inline/issue_78442.rs +++ b/tests/mir-opt/inline/issue_78442.rs @@ -1,4 +1,3 @@ -// skip-filecheck // compile-flags: -Z mir-opt-level=3 -Z inline-mir // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] @@ -9,6 +8,11 @@ pub fn bar

( // Error won't happen if "bar" is not generic _baz: P, ) { + // CHECK-LABEL: fn bar( + // CHECK: let mut {{.*}}: &fn() {foo}; + // CHECK: let {{.*}}: fn() {foo}; + // CHECK: (inlined hide_foo) + // CHECK-NOT: inlined hide_foo()(); } From 6e047c07a66ed5a69e38e38191c911b7cb579e9e Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 22:18:02 -0700 Subject: [PATCH 31/41] FileCheck unchecked_shifts --- tests/mir-opt/inline/unchecked_shifts.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/unchecked_shifts.rs b/tests/mir-opt/inline/unchecked_shifts.rs index 67666f2f713f2..805195dd8b375 100644 --- a/tests/mir-opt/inline/unchecked_shifts.rs +++ b/tests/mir-opt/inline/unchecked_shifts.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] #![feature(unchecked_math)] @@ -9,23 +8,31 @@ // EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff // EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 { + // CHECK-LABEL: fn unchecked_shl_unsigned_smaller( + // CHECK: (inlined core::num::::unchecked_shl) a.unchecked_shl(b) } // EMIT_MIR unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff // EMIT_MIR unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 { + // CHECK-LABEL: fn unchecked_shr_signed_smaller( + // CHECK: (inlined core::num::::unchecked_shr) a.unchecked_shr(b) } // EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_bigger.Inline.diff // EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_bigger.PreCodegen.after.mir pub unsafe fn unchecked_shl_unsigned_bigger(a: u64, b: u32) -> u64 { + // CHECK-LABEL: fn unchecked_shl_unsigned_bigger( + // CHECK: (inlined core::num::::unchecked_shl) a.unchecked_shl(b) } // EMIT_MIR unchecked_shifts.unchecked_shr_signed_bigger.Inline.diff // EMIT_MIR unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.mir pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 { + // CHECK-LABEL: fn unchecked_shr_signed_bigger( + // CHECK: (inlined core::num::::unchecked_shr) a.unchecked_shr(b) } From 3faf05b6e7bfc88f2415cd4c09968ffe454b295f Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 22:21:03 -0700 Subject: [PATCH 32/41] FileCheck unsized_argument --- tests/mir-opt/inline/unsized_argument.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/unsized_argument.rs b/tests/mir-opt/inline/unsized_argument.rs index 22c88b83f9b1b..e8c2bc10be220 100644 --- a/tests/mir-opt/inline/unsized_argument.rs +++ b/tests/mir-opt/inline/unsized_argument.rs @@ -1,4 +1,3 @@ -// skip-filecheck // needs-unwind #![feature(unsized_fn_params)] @@ -7,6 +6,8 @@ fn callee(y: [i32]) {} // EMIT_MIR unsized_argument.caller.Inline.diff fn caller(x: Box<[i32]>) { + // CHECK-LABEL: fn caller( + // CHECK-NOT: (inlined callee) callee(*x); } From 6ab66c3f3724e71d228d498a52f02cb358f9247e Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Fri, 20 Oct 2023 22:22:32 -0700 Subject: [PATCH 33/41] FileCheck unwrap_unchecked --- tests/mir-opt/inline/unwrap_unchecked.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/inline/unwrap_unchecked.rs b/tests/mir-opt/inline/unwrap_unchecked.rs index f8964eba227a4..be133706e5c22 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.rs +++ b/tests/mir-opt/inline/unwrap_unchecked.rs @@ -1,4 +1,3 @@ -// skip-filecheck #![crate_type = "lib"] // EMIT_MIR_FOR_EACH_PANIC_STRATEGY @@ -8,5 +7,7 @@ // EMIT_MIR unwrap_unchecked.unwrap_unchecked.Inline.diff // EMIT_MIR unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir pub unsafe fn unwrap_unchecked(slf: Option) -> T { + // CHECK-LABEL: fn unwrap_unchecked( + // CHECK: (inlined #[track_caller] Option::::unwrap_unchecked) slf.unwrap_unchecked() } From 1ec10ec77f6fa64de7c03150bfbb831dec376357 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Sun, 22 Oct 2023 09:27:43 -0700 Subject: [PATCH 34/41] address review comments --- tests/mir-opt/inline/asm_unwind.rs | 3 + .../inline/caller_with_trivial_bound.rs | 3 + tests/mir-opt/inline/cycle.rs | 2 + .../inline/dont_ice_on_generic_rust_call.rs | 2 +- tests/mir-opt/inline/dyn_trait.rs | 4 +- tests/mir-opt/inline/exponential_runtime.rs | 1 + tests/mir-opt/inline/inline_box_fn.rs | 2 +- .../inline/inline_retag.bar.Inline.after.mir | 59 ----------------- .../inline/inline_retag.bar.Inline.diff | 65 +++++++++++++++++++ tests/mir-opt/inline/inline_retag.rs | 11 +++- tests/mir-opt/inline/inline_trait_method.rs | 3 +- ...ine_scopes_parenting.main.Inline.after.mir | 6 +- .../issue_76997_inline_scopes_parenting.rs | 9 ++- 13 files changed, 100 insertions(+), 70 deletions(-) delete mode 100644 tests/mir-opt/inline/inline_retag.bar.Inline.after.mir create mode 100644 tests/mir-opt/inline/inline_retag.bar.Inline.diff diff --git a/tests/mir-opt/inline/asm_unwind.rs b/tests/mir-opt/inline/asm_unwind.rs index 596a4592f25ff..0ae20e5221110 100644 --- a/tests/mir-opt/inline/asm_unwind.rs +++ b/tests/mir-opt/inline/asm_unwind.rs @@ -2,6 +2,7 @@ // // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // needs-asm-support +// needs-unwind // compile-flags: -Zinline-mir-hint-threshold=1000 #![feature(asm_unwind)] @@ -21,5 +22,7 @@ fn foo() { pub fn main() { // CHECK-LABEL: fn main( // CHECK: (inlined foo) + // CHECK: asm!("", options(MAY_UNWIND)) -> [return: {{bb.*}}, unwind: [[unwind:bb.*]]]; + // CHECK: [[unwind]] (cleanup) foo(); } diff --git a/tests/mir-opt/inline/caller_with_trivial_bound.rs b/tests/mir-opt/inline/caller_with_trivial_bound.rs index 722c7f6724efd..40f7f4bbab2f7 100644 --- a/tests/mir-opt/inline/caller_with_trivial_bound.rs +++ b/tests/mir-opt/inline/caller_with_trivial_bound.rs @@ -15,6 +15,9 @@ impl Factory for IntFactory { // EMIT_MIR caller_with_trivial_bound.foo.Inline.diff pub fn foo() where + // Because of this trivial bound, the inliner fails to normalize + // `>::Item`. + // Verify that we do not inline anything, which would cause validation ICEs. IntFactory: Factory, { // CHECK-LABEL: fn foo( diff --git a/tests/mir-opt/inline/cycle.rs b/tests/mir-opt/inline/cycle.rs index 8716b44b3dc02..350724235ba04 100644 --- a/tests/mir-opt/inline/cycle.rs +++ b/tests/mir-opt/inline/cycle.rs @@ -13,6 +13,7 @@ fn f(g: impl Fn()) { #[inline(always)] fn g() { // CHECK-LABEL: fn g( + // CHECK-NOT: inlined // CHECK: (inlined f::) // CHECK-NOT: inlined f(main); @@ -21,6 +22,7 @@ fn g() { // EMIT_MIR cycle.main.Inline.diff fn main() { // CHECK-LABEL: fn main( + // CHECK-NOT: inlined // CHECK: (inlined f::) // CHECK-NOT: inlined f(g); diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs index 3307a1408fb56..ce5e1855a716b 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs @@ -8,6 +8,6 @@ use std::marker::Tuple; // EMIT_MIR dont_ice_on_generic_rust_call.call.Inline.diff pub fn call(mut mock: Box>, input: I) { // CHECK-LABEL: fn call( - // CHECK-NOT: (inlined > as FnMut>::call_mut) + // CHECK-NOT: inlined mock.call_mut(input) } diff --git a/tests/mir-opt/inline/dyn_trait.rs b/tests/mir-opt/inline/dyn_trait.rs index 005cf155fdb93..ecf220a85e6a3 100644 --- a/tests/mir-opt/inline/dyn_trait.rs +++ b/tests/mir-opt/inline/dyn_trait.rs @@ -20,7 +20,7 @@ pub trait Query { #[inline(always)] pub fn mk_cycle(c: &dyn Cache) { // CHECK-LABEL: fn mk_cycle( - // CHECK-NOT: (inlined as Cache>::store_nocache) + // CHECK-NOT: inlined c.store_nocache() } @@ -36,7 +36,7 @@ pub fn try_execute_query(c: &C) { #[inline(always)] pub fn get_query(t: &T) { // CHECK-LABEL: fn get_query( - // CHECK-NOT: (inlined ::cache::) + // CHECK-NOT: inlined let c = Q::cache(t); // CHECK: (inlined try_execute_query::<::C>) // CHECK: (inlined mk_cycle::<::V>) diff --git a/tests/mir-opt/inline/exponential_runtime.rs b/tests/mir-opt/inline/exponential_runtime.rs index 499bec33ffc9b..1199ce4e5588e 100644 --- a/tests/mir-opt/inline/exponential_runtime.rs +++ b/tests/mir-opt/inline/exponential_runtime.rs @@ -85,6 +85,7 @@ impl A for () { // EMIT_MIR exponential_runtime.main.Inline.diff fn main() { // CHECK-LABEL: fn main( + // CHECK-NOT: inlined // CHECK: (inlined <() as G>::call) // CHECK: (inlined <() as F>::call) // CHECK: (inlined <() as E>::call) diff --git a/tests/mir-opt/inline/inline_box_fn.rs b/tests/mir-opt/inline/inline_box_fn.rs index 7686477c291a3..d2da239399235 100644 --- a/tests/mir-opt/inline/inline_box_fn.rs +++ b/tests/mir-opt/inline/inline_box_fn.rs @@ -5,6 +5,6 @@ // EMIT_MIR inline_box_fn.call.Inline.diff fn call(x: Box) { // CHECK-LABEL: fn call( - // CHECK-NOT: (inlined as Fn<(i32,)>>::call) + // CHECK-NOT: inlined x(1); } diff --git a/tests/mir-opt/inline/inline_retag.bar.Inline.after.mir b/tests/mir-opt/inline/inline_retag.bar.Inline.after.mir deleted file mode 100644 index 8c3f3a4589e63..0000000000000 --- a/tests/mir-opt/inline/inline_retag.bar.Inline.after.mir +++ /dev/null @@ -1,59 +0,0 @@ -// MIR for `bar` after Inline - -fn bar() -> bool { - let mut _0: bool; - let _1: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; - let mut _2: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; - let mut _3: &i32; - let _4: &i32; - let _5: i32; - let mut _6: &i32; - let _7: &i32; - let _8: i32; - scope 1 { - debug f => _1; - let mut _9: &i32; - let mut _10: &i32; - scope 2 (inlined foo) { - debug x => _3; - debug y => _6; - let mut _11: i32; - let mut _12: i32; - } - } - - bb0: { - StorageLive(_1); - _1 = foo; - StorageLive(_2); - _2 = _1; - StorageLive(_3); - StorageLive(_4); - _10 = const _; - Retag(_10); - _4 = &(*_10); - _3 = &(*_4); - StorageLive(_6); - StorageLive(_7); - _9 = const _; - Retag(_9); - _7 = &(*_9); - _6 = &(*_7); - Retag(_3); - Retag(_6); - StorageLive(_11); - _11 = (*_3); - StorageLive(_12); - _12 = (*_6); - _0 = Eq(move _11, move _12); - StorageDead(_12); - StorageDead(_11); - StorageDead(_6); - StorageDead(_3); - StorageDead(_2); - StorageDead(_1); - StorageDead(_7); - StorageDead(_4); - return; - } -} diff --git a/tests/mir-opt/inline/inline_retag.bar.Inline.diff b/tests/mir-opt/inline/inline_retag.bar.Inline.diff new file mode 100644 index 0000000000000..8f53f6342ec6d --- /dev/null +++ b/tests/mir-opt/inline/inline_retag.bar.Inline.diff @@ -0,0 +1,65 @@ +- // MIR for `bar` before Inline ++ // MIR for `bar` after Inline + + fn bar() -> bool { + let mut _0: bool; + let _1: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; + let mut _2: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; + let mut _3: &i32; + let _4: &i32; + let _5: i32; + let mut _6: &i32; + let _7: &i32; + let _8: i32; + scope 1 { + debug f => _1; + let mut _9: &i32; + let mut _10: &i32; ++ scope 2 (inlined foo) { ++ debug x => _3; ++ debug y => _6; ++ let mut _11: i32; ++ let mut _12: i32; ++ } + } + + bb0: { + StorageLive(_1); + _1 = foo; + StorageLive(_2); + _2 = _1; + StorageLive(_3); + StorageLive(_4); + _10 = const _; + Retag(_10); + _4 = &(*_10); + _3 = &(*_4); + StorageLive(_6); + StorageLive(_7); + _9 = const _; + Retag(_9); + _7 = &(*_9); + _6 = &(*_7); +- _0 = move _2(move _3, move _6) -> [return: bb1, unwind continue]; +- } +- +- bb1: { ++ Retag(_3); ++ Retag(_6); ++ StorageLive(_11); ++ _11 = (*_3); ++ StorageLive(_12); ++ _12 = (*_6); ++ _0 = Eq(move _11, move _12); ++ StorageDead(_12); ++ StorageDead(_11); + StorageDead(_6); + StorageDead(_3); + StorageDead(_2); + StorageDead(_1); + StorageDead(_7); + StorageDead(_4); + return; + } + } + diff --git a/tests/mir-opt/inline/inline_retag.rs b/tests/mir-opt/inline/inline_retag.rs index c90c0b819b7ba..b9058905892bf 100644 --- a/tests/mir-opt/inline/inline_retag.rs +++ b/tests/mir-opt/inline/inline_retag.rs @@ -6,10 +6,19 @@ fn main() { println!("{}", bar()); } -// EMIT_MIR inline_retag.bar.Inline.after.mir +// EMIT_MIR inline_retag.bar.Inline.diff fn bar() -> bool { // CHECK-LABEL: fn bar( // CHECK: (inlined foo) + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug y => [[y:_.*]]; + // CHECK: bb0: { + // CHECK: Retag + // CHECK: Retag + // CHECK: Retag([[x]]); + // CHECK: Retag([[y]]); + // CHECK: return; + // CHECK-NEXT: } let f = foo; f(&1, &-1) } diff --git a/tests/mir-opt/inline/inline_trait_method.rs b/tests/mir-opt/inline/inline_trait_method.rs index ea09966a2aa94..b39355637a1c5 100644 --- a/tests/mir-opt/inline/inline_trait_method.rs +++ b/tests/mir-opt/inline/inline_trait_method.rs @@ -1,3 +1,4 @@ +// Verify that we do not inline the default impl in a trait object. // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // compile-flags: -Z span_free_formats @@ -8,7 +9,7 @@ fn main() { // EMIT_MIR inline_trait_method.test.Inline.after.mir fn test(x: &dyn X) -> u32 { // CHECK-LABEL: fn test( - // CHECK-NOT: (inlined ::y) + // CHECK-NOT: inlined x.y() } diff --git a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir index ba5eb757cf977..ba4f91b28d536 100644 --- a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir +++ b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir @@ -2,8 +2,8 @@ fn main() -> () { let mut _0: (); - let _1: {closure@$DIR/issue_76997_inline_scopes_parenting.rs:10:13: 10:16}; - let mut _2: &{closure@$DIR/issue_76997_inline_scopes_parenting.rs:10:13: 10:16}; + let _1: {closure@$DIR/issue_76997_inline_scopes_parenting.rs:15:13: 15:16}; + let mut _2: &{closure@$DIR/issue_76997_inline_scopes_parenting.rs:15:13: 15:16}; let mut _3: ((),); let mut _4: (); let mut _5: (); @@ -19,7 +19,7 @@ fn main() -> () { bb0: { StorageLive(_1); - _1 = {closure@$DIR/issue_76997_inline_scopes_parenting.rs:10:13: 10:16}; + _1 = {closure@$DIR/issue_76997_inline_scopes_parenting.rs:15:13: 15:16}; StorageLive(_2); _2 = &_1; StorageLive(_3); diff --git a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs index 2a7c931a659ee..2fb363c19044d 100644 --- a/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs +++ b/tests/mir-opt/inline/issue_76997_inline_scopes_parenting.rs @@ -3,10 +3,15 @@ // EMIT_MIR issue_76997_inline_scopes_parenting.main.Inline.after.mir fn main() { // CHECK-LABEL: fn main( - // CHECK: scope 2 + // CHECK: scope 1 { + // CHECK-NEXT: debug f + // CHECK-NEXT: scope 2 (inlined main::{closure#0}) { // CHECK-NEXT: debug x - // CHECK-NEXT: scope 3 + // CHECK-NEXT: scope 3 { // CHECK-NEXT: debug y + // CHECK-NEXT: } + // CHECK-NEXT: } + // CHECK-NEXT: } let f = |x| { let y = x; y }; f(()) } From 828f069c12b356631ef2f7b707d51708861a788d Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 20 Oct 2023 19:33:22 +0200 Subject: [PATCH 35/41] Remove most indentation in check-cfg impl --- compiler/rustc_interface/src/interface.rs | 381 ++++++++++------------ 1 file changed, 181 insertions(+), 200 deletions(-) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index d2ce77ad53511..2218892538212 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -139,7 +139,7 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check let filename = FileName::cfg_spec_source_code(&s); macro_rules! error { - ($reason: expr) => { + ($reason:expr) => { handler.early_error(format!( concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"), s @@ -147,217 +147,198 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check }; } - let expected_error = - || error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`"); - - match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) { - Ok(mut parser) => match parser.parse_meta_item() { - Ok(meta_item) if parser.token == token::Eof => { - if let Some(args) = meta_item.meta_item_list() { - if meta_item.has_name(sym::names) { - // defaults are flipped for the old syntax - if old_syntax == None { - check_cfg.exhaustive_names = false; - check_cfg.exhaustive_values = false; - } - old_syntax = Some(true); - - check_cfg.exhaustive_names = true; - for arg in args { - if arg.is_word() && arg.ident().is_some() { - let ident = arg.ident().expect("multi-segment cfg key"); - check_cfg - .expecteds - .entry(ident.name.to_string()) - .or_insert(ExpectedValues::Any); - } else { - error!("`names()` arguments must be simple identifiers"); - } - } - } else if meta_item.has_name(sym::values) { - // defaults are flipped for the old syntax - if old_syntax == None { - check_cfg.exhaustive_names = false; - check_cfg.exhaustive_values = false; - } - old_syntax = Some(true); - - if let Some((name, values)) = args.split_first() { - if name.is_word() && name.ident().is_some() { - let ident = name.ident().expect("multi-segment cfg key"); - let expected_values = check_cfg - .expecteds - .entry(ident.name.to_string()) - .and_modify(|expected_values| match expected_values { - ExpectedValues::Some(_) => {} - ExpectedValues::Any => { - // handle the case where names(...) was done - // before values by changing to a list - *expected_values = - ExpectedValues::Some(FxHashSet::default()); - } - }) - .or_insert_with(|| { - ExpectedValues::Some(FxHashSet::default()) - }); - - let ExpectedValues::Some(expected_values) = expected_values - else { - bug!("`expected_values` should be a list a values") - }; - - for val in values { - if let Some(LitKind::Str(s, _)) = - val.lit().map(|lit| &lit.kind) - { - expected_values.insert(Some(s.to_string())); - } else { - error!( - "`values()` arguments must be string literals" - ); - } - } - - if values.is_empty() { - expected_values.insert(None); - } - } else { - error!( - "`values()` first argument must be a simple identifier" - ); - } - } else if args.is_empty() { - check_cfg.exhaustive_values = true; - } else { - expected_error(); - } - } else if meta_item.has_name(sym::cfg) { - old_syntax = Some(false); - - let mut names = Vec::new(); - let mut values: FxHashSet<_> = Default::default(); - - let mut any_specified = false; - let mut values_specified = false; - let mut values_any_specified = false; - - for arg in args { - if arg.is_word() && let Some(ident) = arg.ident() { - if values_specified { - error!("`cfg()` names cannot be after values"); - } - names.push(ident); - } else if arg.has_name(sym::any) - && let Some(args) = arg.meta_item_list() - { - if any_specified { - error!("`any()` cannot be specified multiple times"); - } - any_specified = true; - if !args.is_empty() { - error!("`any()` must be empty"); - } - } else if arg.has_name(sym::values) - && let Some(args) = arg.meta_item_list() - { - if names.is_empty() { - error!( - "`values()` cannot be specified before the names" - ); - } else if values_specified { - error!( - "`values()` cannot be specified multiple times" - ); - } - values_specified = true; - - for arg in args { - if let Some(LitKind::Str(s, _)) = - arg.lit().map(|lit| &lit.kind) - { - values.insert(Some(s.to_string())); - } else if arg.has_name(sym::any) - && let Some(args) = arg.meta_item_list() - { - if values_any_specified { - error!( - "`any()` in `values()` cannot be specified multiple times" - ); - } - values_any_specified = true; - if !args.is_empty() { - error!("`any()` must be empty"); - } - } else { - error!( - "`values()` arguments must be string literals or `any()`" - ); - } - } - } else { - error!( - "`cfg()` arguments must be simple identifiers, `any()` or `values(...)`" - ); - } + let expected_error = || -> ! { + error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`") + }; + + let Ok(mut parser) = maybe_new_parser_from_source_str(&sess, filename, s.to_string()) + else { + expected_error(); + }; + + let meta_item = match parser.parse_meta_item() { + Ok(meta_item) if parser.token == token::Eof => meta_item, + Ok(..) => expected_error(), + Err(err) => { + err.cancel(); + expected_error(); + } + }; + + let Some(args) = meta_item.meta_item_list() else { + expected_error(); + }; + + if meta_item.has_name(sym::names) { + // defaults are flipped for the old syntax + if old_syntax == None { + check_cfg.exhaustive_names = false; + check_cfg.exhaustive_values = false; + } + old_syntax = Some(true); + + check_cfg.exhaustive_names = true; + for arg in args { + if arg.is_word() && arg.ident().is_some() { + let ident = arg.ident().expect("multi-segment cfg key"); + check_cfg + .expecteds + .entry(ident.name.to_string()) + .or_insert(ExpectedValues::Any); + } else { + error!("`names()` arguments must be simple identifiers"); + } + } + } else if meta_item.has_name(sym::values) { + // defaults are flipped for the old syntax + if old_syntax == None { + check_cfg.exhaustive_names = false; + check_cfg.exhaustive_values = false; + } + old_syntax = Some(true); + + if let Some((name, values)) = args.split_first() { + if name.is_word() && name.ident().is_some() { + let ident = name.ident().expect("multi-segment cfg key"); + let expected_values = check_cfg + .expecteds + .entry(ident.name.to_string()) + .and_modify(|expected_values| match expected_values { + ExpectedValues::Some(_) => {} + ExpectedValues::Any => { + // handle the case where names(...) was done + // before values by changing to a list + *expected_values = ExpectedValues::Some(FxHashSet::default()); } + }) + .or_insert_with(|| ExpectedValues::Some(FxHashSet::default())); + + let ExpectedValues::Some(expected_values) = expected_values else { + bug!("`expected_values` should be a list a values") + }; - if values.is_empty() && !values_any_specified && !any_specified { - values.insert(None); - } else if !values.is_empty() && values_any_specified { + for val in values { + if let Some(LitKind::Str(s, _)) = val.lit().map(|lit| &lit.kind) { + expected_values.insert(Some(s.to_string())); + } else { + error!("`values()` arguments must be string literals"); + } + } + + if values.is_empty() { + expected_values.insert(None); + } + } else { + error!("`values()` first argument must be a simple identifier"); + } + } else if args.is_empty() { + check_cfg.exhaustive_values = true; + } else { + expected_error(); + } + } else if meta_item.has_name(sym::cfg) { + old_syntax = Some(false); + + let mut names = Vec::new(); + let mut values: FxHashSet<_> = Default::default(); + + let mut any_specified = false; + let mut values_specified = false; + let mut values_any_specified = false; + + for arg in args { + if arg.is_word() && let Some(ident) = arg.ident() { + if values_specified { + error!("`cfg()` names cannot be after values"); + } + names.push(ident); + } else if arg.has_name(sym::any) + && let Some(args) = arg.meta_item_list() + { + if any_specified { + error!("`any()` cannot be specified multiple times"); + } + any_specified = true; + if !args.is_empty() { + error!("`any()` must be empty"); + } + } else if arg.has_name(sym::values) + && let Some(args) = arg.meta_item_list() + { + if names.is_empty() { + error!("`values()` cannot be specified before the names"); + } else if values_specified { + error!("`values()` cannot be specified multiple times"); + } + values_specified = true; + + for arg in args { + if let Some(LitKind::Str(s, _)) = + arg.lit().map(|lit| &lit.kind) + { + values.insert(Some(s.to_string())); + } else if arg.has_name(sym::any) + && let Some(args) = arg.meta_item_list() + { + if values_any_specified { error!( - "`values()` arguments cannot specify string literals and `any()` at the same time" + "`any()` in `values()` cannot be specified multiple times" ); } - - if any_specified { - if !names.is_empty() - || !values.is_empty() - || values_any_specified - { - error!("`cfg(any())` can only be provided in isolation"); - } - - check_cfg.exhaustive_names = false; - } else { - for name in names { - check_cfg - .expecteds - .entry(name.to_string()) - .and_modify(|v| match v { - ExpectedValues::Some(v) - if !values_any_specified => - { - v.extend(values.clone()) - } - ExpectedValues::Some(_) => *v = ExpectedValues::Any, - ExpectedValues::Any => {} - }) - .or_insert_with(|| { - if values_any_specified { - ExpectedValues::Any - } else { - ExpectedValues::Some(values.clone()) - } - }); - } + values_any_specified = true; + if !args.is_empty() { + error!("`any()` must be empty"); } } else { - expected_error(); + error!( + "`values()` arguments must be string literals or `any()`" + ); } - } else { - expected_error(); } + } else { + error!( + "`cfg()` arguments must be simple identifiers, `any()` or `values(...)`" + ); } - Ok(..) => expected_error(), - Err(err) => { - err.cancel(); - expected_error(); + } + + if values.is_empty() && !values_any_specified && !any_specified { + values.insert(None); + } else if !values.is_empty() && values_any_specified { + error!( + "`values()` arguments cannot specify string literals and `any()` at the same time" + ); + } + + if any_specified { + if !names.is_empty() || !values.is_empty() || values_any_specified { + error!("`cfg(any())` can only be provided in isolation"); + } + + check_cfg.exhaustive_names = false; + } else { + for name in names { + check_cfg + .expecteds + .entry(name.to_string()) + .and_modify(|v| match v { + ExpectedValues::Some(v) if !values_any_specified => { + v.extend(values.clone()) + } + ExpectedValues::Some(_) => *v = ExpectedValues::Any, + ExpectedValues::Any => {} + }) + .or_insert_with(|| { + if values_any_specified { + ExpectedValues::Any + } else { + ExpectedValues::Some(values.clone()) + } + }); } - }, - Err(errs) => { - drop(errs); - expected_error(); } + } else { + expected_error(); } } From 1ef96a9e06124ca3ce95f9ceb3be6f24d0e7154a Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 20 Oct 2023 19:34:45 +0200 Subject: [PATCH 36/41] Fix residual (never merged) check-cfg syntax in doc --- src/doc/unstable-book/src/compiler-flags/check-cfg.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/compiler-flags/check-cfg.md b/src/doc/unstable-book/src/compiler-flags/check-cfg.md index 7a3ef5e9e2be6..0e15c79076fa4 100644 --- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md +++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md @@ -139,7 +139,7 @@ fn do_mumble_frotz() {} ```bash # This turns on checking for feature values, but not for condition names. -rustc --check-cfg 'configure(feature, values("zapping", "lasers"))' \ +rustc --check-cfg 'cfg(feature, values("zapping", "lasers"))' \ --check-cfg 'cfg(any())' \ --cfg 'feature="zapping"' -Z unstable-options ``` From b7debe34e6fb2d329e21739c97ce3d7161303af5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 26 Oct 2023 17:18:21 -0700 Subject: [PATCH 37/41] Parse rustc version at compile time --- compiler/rustc_attr/src/builtin.rs | 41 ++++--------- compiler/rustc_attr/src/lib.rs | 2 +- compiler/rustc_macros/src/current_version.rs | 59 +++++++++++++++++++ compiler/rustc_macros/src/lib.rs | 6 ++ compiler/rustc_middle/src/middle/stability.rs | 27 ++++----- compiler/rustc_session/src/lib.rs | 3 + compiler/rustc_session/src/version.rs | 19 ++++++ src/librustdoc/html/render/mod.rs | 5 +- .../clippy_utils/src/qualify_min_const_fn.rs | 23 +++----- 9 files changed, 124 insertions(+), 61 deletions(-) create mode 100644 compiler/rustc_macros/src/current_version.rs create mode 100644 compiler/rustc_session/src/version.rs diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 363ba0d4a815b..ff23e3da43800 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -10,10 +10,9 @@ use rustc_session::config::ExpectedValues; use rustc_session::lint::builtin::UNEXPECTED_CFGS; use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::parse::{feature_err, ParseSess}; -use rustc_session::Session; +use rustc_session::{RustcVersion, Session}; use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; -use std::fmt::{self, Display}; use std::num::NonZeroU32; use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; @@ -24,8 +23,6 @@ use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; /// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591). pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; -pub const CURRENT_RUSTC_VERSION: &str = env!("CFG_RELEASE"); - pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) } @@ -153,7 +150,7 @@ pub enum StabilityLevel { #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(HashStable_Generic)] pub enum Since { - Version(Version), + Version(RustcVersion), /// Stabilized in the upcoming version, whatever number that is. Current, /// Failed to parse a stabilization version. @@ -382,7 +379,7 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit let since = if let Some(since) = since { if since.as_str() == VERSION_PLACEHOLDER { Since::Current - } else if let Some(version) = parse_version(since.as_str(), false) { + } else if let Some(version) = parse_version(since) { Since::Version(version) } else { sess.emit_err(session_diagnostics::InvalidSince { span: attr.span }); @@ -567,31 +564,20 @@ fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &F } } -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[derive(HashStable_Generic)] -pub struct Version { - pub major: u16, - pub minor: u16, - pub patch: u16, -} - -fn parse_version(s: &str, allow_appendix: bool) -> Option { - let mut components = s.split('-'); +/// Parse a rustc version number written inside string literal in an attribute, +/// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are +/// not accepted in this position, unlike when parsing CFG_RELEASE. +fn parse_version(s: Symbol) -> Option { + let mut components = s.as_str().split('-'); let d = components.next()?; - if !allow_appendix && components.next().is_some() { + if components.next().is_some() { return None; } let mut digits = d.splitn(3, '.'); let major = digits.next()?.parse().ok()?; let minor = digits.next()?.parse().ok()?; let patch = digits.next().unwrap_or("0").parse().ok()?; - Some(Version { major, minor, patch }) -} - -impl Display for Version { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch) - } + Some(RustcVersion { major, minor, patch }) } /// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to @@ -623,17 +609,16 @@ pub fn eval_condition( return false; } }; - let Some(min_version) = parse_version(min_version.as_str(), false) else { + let Some(min_version) = parse_version(*min_version) else { sess.emit_warning(session_diagnostics::UnknownVersionLiteral { span: *span }); return false; }; - let rustc_version = parse_version(CURRENT_RUSTC_VERSION, true).unwrap(); // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details if sess.assume_incomplete_release { - rustc_version > min_version + RustcVersion::CURRENT > min_version } else { - rustc_version >= min_version + RustcVersion::CURRENT >= min_version } } ast::MetaItemKind::List(mis) => { diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index 53e3eaaab3768..868c041225581 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -27,6 +27,6 @@ pub use StabilityLevel::*; pub use rustc_ast::attr::*; -pub(crate) use rustc_ast::HashStableContext; +pub(crate) use rustc_session::HashStableContext; fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_macros/src/current_version.rs b/compiler/rustc_macros/src/current_version.rs new file mode 100644 index 0000000000000..5e3b91c17bf6c --- /dev/null +++ b/compiler/rustc_macros/src/current_version.rs @@ -0,0 +1,59 @@ +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::quote; +use syn::parse::{Parse, ParseStream}; +use syn::{parenthesized, parse_macro_input, LitStr, Token}; + +pub struct Input { + variable: LitStr, +} + +mod kw { + syn::custom_keyword!(env); +} + +impl Parse for Input { + // Input syntax is `env!("CFG_RELEASE")` to facilitate grepping. + fn parse(input: ParseStream<'_>) -> syn::Result { + let paren; + input.parse::()?; + input.parse::()?; + parenthesized!(paren in input); + let variable: LitStr = paren.parse()?; + Ok(Input { variable }) + } +} + +pub(crate) fn current_version(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as Input); + + TokenStream::from(match RustcVersion::parse_env_var(&input.variable) { + Ok(RustcVersion { major, minor, patch }) => quote!( + Self { major: #major, minor: #minor, patch: #patch } + ), + Err(err) => syn::Error::new(Span::call_site(), err).into_compile_error(), + }) +} + +struct RustcVersion { + major: u16, + minor: u16, + patch: u16, +} + +impl RustcVersion { + fn parse_env_var(env_var: &LitStr) -> Result> { + let value = proc_macro::tracked_env::var(env_var.value())?; + Self::parse_str(&value) + .ok_or_else(|| format!("failed to parse rustc version: {:?}", value).into()) + } + + fn parse_str(value: &str) -> Option { + // Ignore any suffixes such as "-dev" or "-nightly". + let mut components = value.split('-').next().unwrap().splitn(3, '.'); + let major = components.next()?.parse().ok()?; + let minor = components.next()?.parse().ok()?; + let patch = components.next().unwrap_or("0").parse().ok()?; + Some(RustcVersion { major, minor, patch }) + } +} diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 776ba8f9ca11a..193dbd75fbd57 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -15,6 +15,7 @@ use synstructure::decl_derive; use proc_macro::TokenStream; +mod current_version; mod diagnostics; mod hash_stable; mod lift; @@ -25,6 +26,11 @@ mod symbols; mod type_foldable; mod type_visitable; +#[proc_macro] +pub fn current_rustc_version(input: TokenStream) -> TokenStream { + current_version::current_version(input) +} + #[proc_macro] pub fn rustc_queries(input: TokenStream) -> TokenStream { query::rustc_queries(input) diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 84893b8e627a9..20547696d5a73 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE}; use rustc_session::lint::{BuiltinLintDiagnostics, Level, Lint, LintBuffer}; use rustc_session::parse::feature_err_issue; -use rustc_session::Session; +use rustc_session::{RustcVersion, Session}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use std::num::NonZeroU32; @@ -129,11 +129,6 @@ pub fn deprecation_in_effect(depr: &Deprecation) -> bool { let is_since_rustc_version = depr.is_since_rustc_version; let since = depr.since.as_ref().map(Symbol::as_str); - fn parse_version(ver: &str) -> Vec { - // We ignore non-integer components of the version (e.g., "nightly"). - ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect() - } - if !is_since_rustc_version { // The `since` field doesn't have semantic purpose without `#![staged_api]`. return true; @@ -144,16 +139,18 @@ pub fn deprecation_in_effect(depr: &Deprecation) -> bool { return false; } - if let Some(rustc) = option_env!("CFG_RELEASE") { - let since: Vec = parse_version(&since); - let rustc: Vec = parse_version(rustc); - // We simply treat invalid `since` attributes as relating to a previous - // Rust version, thus always displaying the warning. - if since.len() != 3 { - return true; - } - return since <= rustc; + // We ignore non-integer components of the version (e.g., "nightly"). + let since: Vec = + since.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect(); + + // We simply treat invalid `since` attributes as relating to a previous + // Rust version, thus always displaying the warning. + if since.len() != 3 { + return true; } + + let rustc = RustcVersion::CURRENT; + return since.as_slice() <= &[rustc.major, rustc.minor, rustc.patch]; }; // Assume deprecation is in effect if "since" field is missing diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 7da0bcf01bfbf..17ac3e991c58c 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -43,6 +43,9 @@ pub mod output; pub use getopts; +mod version; +pub use version::RustcVersion; + fluent_messages! { "../messages.ftl" } /// Requirements for a `StableHashingContext` to be used in this crate. diff --git a/compiler/rustc_session/src/version.rs b/compiler/rustc_session/src/version.rs new file mode 100644 index 0000000000000..1ad8620bfba55 --- /dev/null +++ b/compiler/rustc_session/src/version.rs @@ -0,0 +1,19 @@ +use std::fmt::{self, Display}; + +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(HashStable_Generic)] +pub struct RustcVersion { + pub major: u16, + pub minor: u16, + pub patch: u16, +} + +impl RustcVersion { + pub const CURRENT: Self = current_rustc_version!(env!("CFG_RELEASE")); +} + +impl Display for RustcVersion { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch) + } +} diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index e01341acf438e..88d01b7a5e57d 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -48,13 +48,14 @@ use std::str; use std::string::ToString; use askama::Template; -use rustc_attr::{ConstStability, Deprecation, Since, StabilityLevel, CURRENT_RUSTC_VERSION}; +use rustc_attr::{ConstStability, Deprecation, Since, StabilityLevel}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::Mutability; use rustc_middle::middle::stability; use rustc_middle::ty::{self, TyCtxt}; +use rustc_session::RustcVersion; use rustc_span::{ symbol::{sym, Symbol}, BytePos, FileName, RealFileName, @@ -979,7 +980,7 @@ fn render_stability_since_raw_with_extra( fn since_to_string(since: &Since) -> Option { match since { Since::Version(since) => Some(since.to_string()), - Since::Current => Some(CURRENT_RUSTC_VERSION.to_owned()), + Since::Current => Some(RustcVersion::CURRENT.to_string()), Since::Err => None, } } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 1e465ac91b76e..31f7b87de635e 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -5,7 +5,7 @@ use crate::msrvs::Msrv; use hir::LangItem; -use rustc_attr::{Since, CURRENT_RUSTC_VERSION}; +use rustc_attr::Since; use rustc_const_eval::transform::check_consts::ConstCx; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -372,23 +372,16 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool { // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262. let const_stab_rust_version = match since { - Since::Version(version) => RustcVersion::new( - u32::from(version.major), - u32::from(version.minor), - u32::from(version.patch), - ), - Since::Current => { - // HACK(nilstrieb): CURRENT_RUSTC_VERSION can return versions like 1.66.0-dev. - // `rustc-semver` doesn't accept the `-dev` version number so we have to strip it off. - let short_version = CURRENT_RUSTC_VERSION.split('-').next().unwrap(); - RustcVersion::parse(short_version).unwrap_or_else(|err| { - panic!("`rustc_attr::StabilityLevel::Stable::since` is ill-formatted: `{CURRENT_RUSTC_VERSION}`, {err:?}") - }) - }, + Since::Version(version) => version, + Since::Current => rustc_session::RustcVersion::CURRENT, Since::Err => return false, }; - msrv.meets(const_stab_rust_version) + msrv.meets(RustcVersion::new( + u32::from(const_stab_rust_version.major), + u32::from(const_stab_rust_version.minor), + u32::from(const_stab_rust_version.patch), + )) } else { // Unstable const fn with the feature enabled. msrv.current().is_none() From 84a1a689ccc8eb6b8be48f3385bc9b0aeb5c71a6 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 21 Oct 2023 19:11:24 +0200 Subject: [PATCH 38/41] Better guard against wrong input with check-cfg any() --- compiler/rustc_interface/src/interface.rs | 10 +++++++--- tests/ui/check-cfg/invalid-arguments.any_values.stderr | 2 ++ tests/ui/check-cfg/invalid-arguments.rs | 4 +++- .../ui/check-cfg/invalid-arguments.unterminated.stderr | 2 ++ 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 tests/ui/check-cfg/invalid-arguments.any_values.stderr create mode 100644 tests/ui/check-cfg/invalid-arguments.unterminated.stderr diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 2218892538212..422c2fc65ad6a 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -311,11 +311,15 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check } if any_specified { - if !names.is_empty() || !values.is_empty() || values_any_specified { + if names.is_empty() + && values.is_empty() + && !values_specified + && !values_any_specified + { + check_cfg.exhaustive_names = false; + } else { error!("`cfg(any())` can only be provided in isolation"); } - - check_cfg.exhaustive_names = false; } else { for name in names { check_cfg diff --git a/tests/ui/check-cfg/invalid-arguments.any_values.stderr b/tests/ui/check-cfg/invalid-arguments.any_values.stderr new file mode 100644 index 0000000000000..f9a9c4a6e1328 --- /dev/null +++ b/tests/ui/check-cfg/invalid-arguments.any_values.stderr @@ -0,0 +1,2 @@ +error: invalid `--check-cfg` argument: `cfg(any(),values())` (`values()` cannot be specified before the names) + diff --git a/tests/ui/check-cfg/invalid-arguments.rs b/tests/ui/check-cfg/invalid-arguments.rs index 79bef89c95740..a56f48e0af93d 100644 --- a/tests/ui/check-cfg/invalid-arguments.rs +++ b/tests/ui/check-cfg/invalid-arguments.rs @@ -6,7 +6,7 @@ // revisions: multiple_values_any not_empty_any not_empty_values_any // revisions: values_any_missing_values values_any_before_ident ident_in_values_1 // revisions: ident_in_values_2 unknown_meta_item_1 unknown_meta_item_2 unknown_meta_item_3 -// revisions: mixed_values_any mixed_any giberich +// revisions: mixed_values_any mixed_any any_values giberich unterminated // // compile-flags: -Z unstable-options // [anything_else]compile-flags: --check-cfg=anything_else(...) @@ -29,6 +29,8 @@ // [unknown_meta_item_3]compile-flags: --check-cfg=cfg(foo,values(test())) // [mixed_values_any]compile-flags: --check-cfg=cfg(foo,values("bar",any())) // [mixed_any]compile-flags: --check-cfg=cfg(any(),values(any())) +// [any_values]compile-flags: --check-cfg=cfg(any(),values()) // [giberich]compile-flags: --check-cfg=cfg(...) +// [unterminated]compile-flags: --check-cfg=cfg( fn main() {} diff --git a/tests/ui/check-cfg/invalid-arguments.unterminated.stderr b/tests/ui/check-cfg/invalid-arguments.unterminated.stderr new file mode 100644 index 0000000000000..80161a6aa0fc8 --- /dev/null +++ b/tests/ui/check-cfg/invalid-arguments.unterminated.stderr @@ -0,0 +1,2 @@ +error: invalid `--check-cfg` argument: `cfg(` (expected `cfg(name, values("value1", "value2", ... "valueN"))`) + From 2ef5897a89f9bbd9d38b9eb1222b5bedef98814b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 27 Oct 2023 13:19:24 +0200 Subject: [PATCH 39/41] fix failure to detect a too-big-type after adding padding --- compiler/rustc_abi/src/layout.rs | 5 +++++ .../rustc_ty_utils/src/layout_sanity_check.rs | 3 +++ tests/ui/layout/too-big-with-padding.rs | 18 ++++++++++++++++++ tests/ui/layout/too-big-with-padding.stderr | 8 ++++++++ 4 files changed, 34 insertions(+) create mode 100644 tests/ui/layout/too-big-with-padding.rs create mode 100644 tests/ui/layout/too-big-with-padding.stderr diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 00d862ca27b7b..9127e1d06e88f 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -539,6 +539,7 @@ pub trait LayoutCalculator { // Align the maximum variant size to the largest alignment. size = size.align_to(align.abi); + // FIXME(oli-obk): deduplicate and harden these checks if size.bytes() >= dl.obj_size_bound() { return None; } @@ -1103,6 +1104,10 @@ fn univariant< inverse_memory_index.into_iter().map(|it| it.index() as u32).collect() }; let size = min_size.align_to(align.abi); + // FIXME(oli-obk): deduplicate and harden these checks + if size.bytes() >= dl.obj_size_bound() { + return None; + } let mut layout_of_single_non_zst_field = None; let mut abi = Abi::Aggregate { sized }; // Try to make this a Scalar/ScalarPair. diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs index 8633334381ada..6332c614a90bb 100644 --- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs @@ -19,6 +19,9 @@ pub(super) fn sanity_check_layout<'tcx>( if layout.size.bytes() % layout.align.abi.bytes() != 0 { bug!("size is not a multiple of align, in the following layout:\n{layout:#?}"); } + if layout.size.bytes() >= cx.tcx.data_layout.obj_size_bound() { + bug!("size is too large, in the following layout:\n{layout:#?}"); + } if !cfg!(debug_assertions) { // Stop here, the rest is kind of expensive. diff --git a/tests/ui/layout/too-big-with-padding.rs b/tests/ui/layout/too-big-with-padding.rs new file mode 100644 index 0000000000000..cf41ac872c21b --- /dev/null +++ b/tests/ui/layout/too-big-with-padding.rs @@ -0,0 +1,18 @@ +// build-fail +// compile-flags: --target i686-unknown-linux-gnu --crate-type lib +// needs-llvm-components: x86 +#![feature(no_core, lang_items)] +#![allow(internal_features)] +#![no_std] +#![no_core] + +// 0x7fffffff is fine, but after rounding up it becomes too big +#[repr(C, align(2))] +pub struct Example([u8; 0x7fffffff]); + +pub fn lib(_x: Example) {} //~ERROR: too big for the current architecture + +#[lang = "sized"] +pub trait Sized {} +#[lang = "copy"] +pub trait Copy: Sized {} diff --git a/tests/ui/layout/too-big-with-padding.stderr b/tests/ui/layout/too-big-with-padding.stderr new file mode 100644 index 0000000000000..5cc854adce0d3 --- /dev/null +++ b/tests/ui/layout/too-big-with-padding.stderr @@ -0,0 +1,8 @@ +error: values of the type `Example` are too big for the current architecture + --> $DIR/too-big-with-padding.rs:13:1 + | +LL | pub fn lib(_x: Example) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 6dbad236419075603a616e7b19f585a1a308cf56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 19 Oct 2023 16:34:41 +0000 Subject: [PATCH 40/41] When encountering sealed traits, point types that implement it ``` error[E0277]: the trait bound `S: d::Hidden` is not satisfied --> $DIR/sealed-trait-local.rs:53:20 | LL | impl c::Sealed for S {} | ^ the trait `d::Hidden` is not implemented for `S` | note: required by a bound in `c::Sealed` --> $DIR/sealed-trait-local.rs:17:23 | LL | pub trait Sealed: self::d::Hidden { | ^^^^^^^^^^^^^^^ required by this bound in `Sealed` = note: `Sealed` is a "sealed trait", because to implement it you also need to implement `c::d::Hidden`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it = help: the following types implement the trait: - c::X - c::Y ``` The last `help` is new. --- .../src/traits/error_reporting/suggestions.rs | 30 ++++++++++++- .../sealed-traits/sealed-trait-local.rs | 40 ++++++++++++++++- .../sealed-traits/sealed-trait-local.stderr | 44 ++++++++++++++++--- 3 files changed, 105 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 947ea3eece3f0..aad07d7683a75 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2691,8 +2691,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let DefKind::Trait = tcx.def_kind(item_def_id) && !visible_item { - // FIXME(estebank): extend this to search for all the types that do - // implement this trait and list them. err.note(format!( "`{short_item_name}` is a \"sealed trait\", because to implement \ it you also need to implement `{}`, which is not accessible; \ @@ -2700,6 +2698,34 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { types that already implement it", with_no_trimmed_paths!(tcx.def_path_str(def_id)), )); + let impls_of = tcx.trait_impls_of(def_id); + let impls = impls_of + .non_blanket_impls() + .values() + .flatten() + .chain(impls_of.blanket_impls().iter()) + .collect::>(); + if !impls.is_empty() { + let len = impls.len(); + let mut types = impls.iter() + .map(|t| with_no_trimmed_paths!(format!( + " {}", + tcx.type_of(*t).instantiate_identity(), + ))) + .collect::>(); + let post = if types.len() > 9 { + types.truncate(8); + format!("\nand {} others", len - 8) + } else { + String::new() + }; + err.help(format!( + "the following type{} implement{} the trait:\n{}{post}", + pluralize!(len), + if len == 1 { "s" } else { "" }, + types.join("\n"), + )); + } } } } else { diff --git a/tests/ui/privacy/sealed-traits/sealed-trait-local.rs b/tests/ui/privacy/sealed-traits/sealed-trait-local.rs index 778ddf0f81763..9ae01259a7810 100644 --- a/tests/ui/privacy/sealed-traits/sealed-trait-local.rs +++ b/tests/ui/privacy/sealed-traits/sealed-trait-local.rs @@ -13,7 +13,43 @@ pub mod a { } } -struct S; -impl a::Sealed for S {} //~ ERROR the trait bound `S: Hidden` is not satisfied +pub mod c { + pub trait Sealed: self::d::Hidden { + fn foo() {} + } + + struct X; + impl Sealed for X {} + impl self::d::Hidden for X {} + + struct Y; + impl Sealed for Y {} + impl self::d::Hidden for Y {} + + mod d { + pub trait Hidden {} + } +} +pub mod e { + pub trait Sealed: self::f::Hidden { + fn foo() {} + } + + struct X; + impl self::f::Hidden for X {} + + struct Y; + impl self::f::Hidden for Y {} + impl Sealed for T {} + + mod f { + pub trait Hidden {} + } +} + +struct S; +impl a::Sealed for S {} //~ ERROR the trait bound +impl c::Sealed for S {} //~ ERROR the trait bound +impl e::Sealed for S {} //~ ERROR the trait bound fn main() {} diff --git a/tests/ui/privacy/sealed-traits/sealed-trait-local.stderr b/tests/ui/privacy/sealed-traits/sealed-trait-local.stderr index 5f8076fc84d0e..a7f77a1c0c020 100644 --- a/tests/ui/privacy/sealed-traits/sealed-trait-local.stderr +++ b/tests/ui/privacy/sealed-traits/sealed-trait-local.stderr @@ -1,16 +1,50 @@ -error[E0277]: the trait bound `S: Hidden` is not satisfied - --> $DIR/sealed-trait-local.rs:17:20 +error[E0277]: the trait bound `S: b::Hidden` is not satisfied + --> $DIR/sealed-trait-local.rs:52:20 | LL | impl a::Sealed for S {} - | ^ the trait `Hidden` is not implemented for `S` + | ^ the trait `b::Hidden` is not implemented for `S` | -note: required by a bound in `Sealed` +note: required by a bound in `a::Sealed` --> $DIR/sealed-trait-local.rs:3:23 | LL | pub trait Sealed: self::b::Hidden { | ^^^^^^^^^^^^^^^ required by this bound in `Sealed` = note: `Sealed` is a "sealed trait", because to implement it you also need to implement `a::b::Hidden`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it + = help: the following type implements the trait: + a::X -error: aborting due to previous error +error[E0277]: the trait bound `S: d::Hidden` is not satisfied + --> $DIR/sealed-trait-local.rs:53:20 + | +LL | impl c::Sealed for S {} + | ^ the trait `d::Hidden` is not implemented for `S` + | +note: required by a bound in `c::Sealed` + --> $DIR/sealed-trait-local.rs:17:23 + | +LL | pub trait Sealed: self::d::Hidden { + | ^^^^^^^^^^^^^^^ required by this bound in `Sealed` + = note: `Sealed` is a "sealed trait", because to implement it you also need to implement `c::d::Hidden`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it + = help: the following types implement the trait: + c::X + c::Y + +error[E0277]: the trait bound `S: f::Hidden` is not satisfied + --> $DIR/sealed-trait-local.rs:54:20 + | +LL | impl e::Sealed for S {} + | ^ the trait `f::Hidden` is not implemented for `S` + | +note: required by a bound in `e::Sealed` + --> $DIR/sealed-trait-local.rs:35:23 + | +LL | pub trait Sealed: self::f::Hidden { + | ^^^^^^^^^^^^^^^ required by this bound in `Sealed` + = note: `Sealed` is a "sealed trait", because to implement it you also need to implement `e::f::Hidden`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it + = help: the following types implement the trait: + e::X + e::Y + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. From a65d99d08702b9ceea0d153e432f5bd5f58a783a Mon Sep 17 00:00:00 2001 From: Milo <50248166+Milo123459@users.noreply.github.com> Date: Fri, 27 Oct 2023 20:14:49 +0100 Subject: [PATCH 41/41] Update type_err_ctxt_ext.rs Co-authored-by: Esteban Kuber --- .../src/traits/error_reporting/type_err_ctxt_ext.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index f83ee576c2941..3e7b713208214 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -437,10 +437,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { format!(" in `{t}`"), format!("within `{t}`, "), s.map(|s| (format!("within this `{t}`"), s)), - file.and_then(|file| Some(format!( + file.map(|file| format!( "the full trait has been written to '{}'", file.display(), - ))) + )) ) }) .unwrap_or_default();