diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 8405ae6ff8e8b..62dc7ae58a2f0 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -578,11 +578,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { } } - // All uses of `gate_all!` below this point were added in #65742, + // All uses of `gate_all_legacy_dont_use!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). // We emit an early future-incompatible warning for these. // New syntax gates should go above here to get a hard error gate. - macro_rules! gate_all { + macro_rules! gate_all_legacy_dont_use { ($gate:ident, $msg:literal) => { for span in spans.get(&sym::$gate).unwrap_or(&vec![]) { gate_feature_post!(future_incompatible; &visitor, $gate, *span, $msg); @@ -590,13 +590,19 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { }; } - gate_all!(trait_alias, "trait aliases are experimental"); - gate_all!(associated_type_bounds, "associated type bounds are unstable"); - gate_all!(return_type_notation, "return type notation is experimental"); - gate_all!(decl_macro, "`macro` is experimental"); - gate_all!(box_patterns, "box pattern syntax is experimental"); - gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental"); - gate_all!(try_blocks, "`try` blocks are unstable"); + gate_all_legacy_dont_use!(trait_alias, "trait aliases are experimental"); + gate_all_legacy_dont_use!(associated_type_bounds, "associated type bounds are unstable"); + // Despite being a new feature, `where T: Trait`, which is RTN syntax now, + // used to be gated under associated_type_bounds, which are right above, so RTN needs to + // be too. + gate_all_legacy_dont_use!(return_type_notation, "return type notation is experimental"); + gate_all_legacy_dont_use!(decl_macro, "`macro` is experimental"); + gate_all_legacy_dont_use!(box_patterns, "box pattern syntax is experimental"); + gate_all_legacy_dont_use!( + exclusive_range_pattern, + "exclusive range pattern syntax is experimental" + ); + gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable"); visit::walk_crate(&mut visitor, krate); } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index ed938761694dc..11874898a5adb 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -335,12 +335,20 @@ fn build_subroutine_type_di_node<'ll, 'tcx>( // This is actually a function pointer, so wrap it in pointer DI. let name = compute_debuginfo_type_name(cx.tcx, fn_ty, false); + let (size, align) = match fn_ty.kind() { + ty::FnDef(..) => (0, 1), + ty::FnPtr(..) => ( + cx.tcx.data_layout.pointer_size.bits(), + cx.tcx.data_layout.pointer_align.abi.bits() as u32, + ), + _ => unreachable!(), + }; let di_node = unsafe { llvm::LLVMRustDIBuilderCreatePointerType( DIB(cx), fn_di_node, - cx.tcx.data_layout.pointer_size.bits(), - cx.tcx.data_layout.pointer_align.abi.bits() as u32, + size, + align, 0, // Ignore DWARF address space. name.as_ptr().cast(), name.len(), diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 01f9f06059426..5e5d1b7c1a4ef 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3201,8 +3201,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { /// Checks that all of the arms in an or-pattern have exactly the /// same set of bindings, with the same binding modes for each. fn check_consistent_bindings(&mut self, pats: &[P]) -> Vec { - let mut missing_vars = FxHashMap::default(); - let mut inconsistent_vars = FxHashMap::default(); + let mut missing_vars = FxIndexMap::default(); + let mut inconsistent_vars = FxIndexMap::default(); // 1) Compute the binding maps of all arms. let maps = pats.iter().map(|pat| self.binding_mode_map(pat)).collect::>(); @@ -3244,10 +3244,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } // 3) Report all missing variables we found. - let mut missing_vars = missing_vars.into_iter().collect::>(); - missing_vars.sort_by_key(|&(sym, ref _err)| sym); - - for (name, mut v) in missing_vars.into_iter() { + for (name, mut v) in missing_vars { if inconsistent_vars.contains_key(&name) { v.could_be_path = false; } @@ -3258,10 +3255,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } // 4) Report all inconsistencies in binding modes we found. - let mut inconsistent_vars = inconsistent_vars.iter().collect::>(); - inconsistent_vars.sort(); for (name, v) in inconsistent_vars { - self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1)); + self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(name, v.1)); } // 5) Finally bubble up all the binding maps. diff --git a/compiler/rustc_target/src/spec/riscv64_linux_android.rs b/compiler/rustc_target/src/spec/riscv64_linux_android.rs index af0d685549414..91f5e562d8b86 100644 --- a/compiler/rustc_target/src/spec/riscv64_linux_android.rs +++ b/compiler/rustc_target/src/spec/riscv64_linux_android.rs @@ -9,7 +9,7 @@ pub fn target() -> Target { options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), - features: "+m,+a,+f,+d,+c".into(), + features: "+m,+a,+f,+d,+c,+Zba,+Zbb,+Zbs".into(), llvm_abiname: "lp64d".into(), supported_sanitizers: SanitizerSet::ADDRESS, max_atomic_width: Some(64), diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index c7fa0dcffa93d..091b51440a6e1 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -531,22 +531,18 @@ impl DebugWithInfcx for TyKind { } Never => write!(f, "!"), Tuple(t) => { - let mut iter = t.clone().into_iter(); - write!(f, "(")?; - - match iter.next() { - None => return write!(f, ")"), - Some(ty) => write!(f, "{:?}", &this.wrap(ty))?, - }; - - match iter.next() { - None => return write!(f, ",)"), - Some(ty) => write!(f, "{:?})", &this.wrap(ty))?, + let mut count = 0; + for ty in t.clone() { + if count > 0 { + write!(f, ", ")?; + } + write!(f, "{:?}", &this.wrap(ty))?; + count += 1; } - - for ty in iter { - write!(f, ", {:?}", &this.wrap(ty))?; + // unary tuples need a trailing comma + if count == 1 { + write!(f, ",")?; } write!(f, ")") } diff --git a/tests/assembly/closure-inherit-target-feature.rs b/tests/assembly/closure-inherit-target-feature.rs new file mode 100644 index 0000000000000..3f39c62663e51 --- /dev/null +++ b/tests/assembly/closure-inherit-target-feature.rs @@ -0,0 +1,58 @@ +// only-x86_64 +// assembly-output: emit-asm +// make sure the feature is not enabled at compile-time +// compile-flags: -C target-feature=-sse4.1 -C llvm-args=-x86-asm-syntax=intel + +#![feature(target_feature_11)] +#![crate_type = "rlib"] + +use std::arch::x86_64::{__m128, _mm_blend_ps}; + +#[no_mangle] +pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128) -> __m128 { + let f = { + // check that _mm_blend_ps is not being inlined into the closure + // CHECK-LABEL: {{sse41_blend_nofeature.*closure.*:}} + // CHECK-NOT: blendps + // CHECK: {{call .*_mm_blend_ps.*}} + // CHECK-NOT: blendps + // CHECK: ret + #[inline(never)] |x, y| _mm_blend_ps(x, y, 0b0101) + }; + f(x, y) +} + +#[target_feature(enable = "sse4.1")] +pub fn sse41_blend_noinline(x: __m128, y: __m128) -> __m128 { + let f = { + // check that _mm_blend_ps is being inlined into the closure + // CHECK-LABEL: {{sse41_blend_noinline.*closure.*:}} + // CHECK-NOT: _mm_blend_ps + // CHECK: blendps + // CHECK-NOT: _mm_blend_ps + // CHECK: ret + #[inline(never)] |x, y| unsafe { + _mm_blend_ps(x, y, 0b0101) + } + }; + f(x, y) +} + +#[no_mangle] +#[target_feature(enable = "sse4.1")] +pub fn sse41_blend_doinline(x: __m128, y: __m128) -> __m128 { + // check that the closure and _mm_blend_ps are being inlined into the function + // CHECK-LABEL: sse41_blend_doinline: + // CHECK-NOT: {{sse41_blend_doinline.*closure.*}} + // CHECK-NOT: _mm_blend_ps + // CHECK: blendps + // CHECK-NOT: {{sse41_blend_doinline.*closure.*}} + // CHECK-NOT: _mm_blend_ps + // CHECK: ret + let f = { + #[inline] |x, y| unsafe { + _mm_blend_ps(x, y, 0b0101) + } + }; + f(x, y) +} diff --git a/tests/codegen/debug-fndef-size.rs b/tests/codegen/debug-fndef-size.rs new file mode 100644 index 0000000000000..2bfd77bade23e --- /dev/null +++ b/tests/codegen/debug-fndef-size.rs @@ -0,0 +1,17 @@ +// Verify that `i32::cmp` FnDef type is declared with size 0 and align 1 in LLVM debuginfo. +// compile-flags: -O -g -Cno-prepopulate-passes + +use std::cmp::Ordering; + +fn foo Ordering>(v1: i32, v2: i32, compare: F) -> Ordering { + compare(&v1, &v2) +} + +pub fn main() { + foo(0, 1, i32::cmp); +} + +// CHECK: %compare.dbg.spill = alloca {}, align 1 +// CHECK: call void @llvm.dbg.declare(metadata ptr %compare.dbg.spill, metadata ![[VAR:.*]], metadata !DIExpression()), !dbg !{{.*}} +// CHECK: ![[TYPE:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "fn(&i32, &i32) -> core::cmp::Ordering", baseType: !{{.*}}, align: 1, dwarfAddressSpace: {{.*}}) +// CHECK: ![[VAR]] = !DILocalVariable(name: "compare", scope: !{{.*}}, file: !{{.*}}, line: {{.*}}, type: ![[TYPE]], align: 1) diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr index 4457b7893d5d2..ddc1109bfce55 100644 --- a/tests/ui/or-patterns/missing-bindings.stderr +++ b/tests/ui/or-patterns/missing-bindings.stderr @@ -87,6 +87,14 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | | | pattern doesn't bind `c` +error[E0408]: variable `b` is not bound in all patterns + --> $DIR/missing-bindings.rs:45:22 + | +LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; + | - ^^^^ pattern doesn't bind `b` + | | + | variable not in all patterns + error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:45:22 | @@ -95,11 +103,19 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | | | variable not in all patterns +error[E0408]: variable `e` is not bound in all patterns + --> $DIR/missing-bindings.rs:45:10 + | +LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; + | ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns + | | + | pattern doesn't bind `e` + error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:45:22 + --> $DIR/missing-bindings.rs:45:33 | LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; - | - ^^^^ pattern doesn't bind `b` + | - ^^^^ pattern doesn't bind `b` | | | variable not in all patterns @@ -119,14 +135,6 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | | | variable not in all patterns -error[E0408]: variable `e` is not bound in all patterns - --> $DIR/missing-bindings.rs:45:10 - | -LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; - | ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns - | | - | pattern doesn't bind `e` - error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:45:33 | @@ -135,14 +143,6 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | | | variable not in all patterns -error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:45:33 - | -LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; - | - ^^^^ pattern doesn't bind `b` - | | - | variable not in all patterns - error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:61:29 | @@ -151,6 +151,14 @@ LL | Ok(a) | Err(_), | | | variable not in all patterns +error[E0408]: variable `b` is not bound in all patterns + --> $DIR/missing-bindings.rs:68:21 + | +LL | A(_, a) | + | ^^^^^^^ pattern doesn't bind `b` +LL | B(b), + | - variable not in all patterns + error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:69:21 | @@ -160,12 +168,13 @@ LL | B(b), | ^^^^ pattern doesn't bind `a` error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:68:21 + --> $DIR/missing-bindings.rs:72:17 | -LL | A(_, a) | - | ^^^^^^^ pattern doesn't bind `b` LL | B(b), | - variable not in all patterns +... +LL | B(_) + | ^^^^ pattern doesn't bind `b` error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:72:17 @@ -177,13 +186,22 @@ LL | B(_) | ^^^^ pattern doesn't bind `a` error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:72:17 + --> $DIR/missing-bindings.rs:57:13 | -LL | B(b), - | - variable not in all patterns +LL | / V1( +LL | | +LL | | +LL | | A( +... | +LL | | B(Ok(a) | Err(a)) +LL | | ) | + | |_____________^ pattern doesn't bind `b` ... -LL | B(_) - | ^^^^ pattern doesn't bind `b` +LL | B(b), + | - variable not in all patterns +... +LL | V3(c), + | ^^^^^ pattern doesn't bind `b` error[E0408]: variable `c` is not bound in all patterns --> $DIR/missing-bindings.rs:57:13 @@ -219,24 +237,6 @@ LL | A(_, a) | LL | V3(c), | ^^^^^ pattern doesn't bind `a` -error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:57:13 - | -LL | / V1( -LL | | -LL | | -LL | | A( -... | -LL | | B(Ok(a) | Err(a)) -LL | | ) | - | |_____________^ pattern doesn't bind `b` -... -LL | B(b), - | - variable not in all patterns -... -LL | V3(c), - | ^^^^^ pattern doesn't bind `b` - error: aborting due to 26 previous errors For more information about this error, try `rustc --explain E0408`. diff --git a/tests/ui/resolve/resolve-inconsistent-names.stderr b/tests/ui/resolve/resolve-inconsistent-names.stderr index 42b7281d7b060..d6240fb8f872c 100644 --- a/tests/ui/resolve/resolve-inconsistent-names.stderr +++ b/tests/ui/resolve/resolve-inconsistent-names.stderr @@ -1,11 +1,3 @@ -error[E0408]: variable `a` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:13:12 - | -LL | a | b => {} - | - ^ pattern doesn't bind `a` - | | - | variable not in all patterns - error[E0408]: variable `b` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:13:8 | @@ -14,6 +6,14 @@ LL | a | b => {} | | | pattern doesn't bind `b` +error[E0408]: variable `a` is not bound in all patterns + --> $DIR/resolve-inconsistent-names.rs:13:12 + | +LL | a | b => {} + | - ^ pattern doesn't bind `a` + | | + | variable not in all patterns + error[E0408]: variable `c` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:19:9 | @@ -54,6 +54,19 @@ LL | (A, B) | (ref B, c) | (c, A) => () | | | first binding +error[E0408]: variable `Const2` is not bound in all patterns + --> $DIR/resolve-inconsistent-names.rs:31:9 + | +LL | (CONST1, _) | (_, Const2) => () + | ^^^^^^^^^^^ ------ variable not in all patterns + | | + | pattern doesn't bind `Const2` + | +help: if you meant to match on constant `m::Const2`, use the full path in the pattern + | +LL | (CONST1, _) | (_, m::Const2) => () + | ~~~~~~~~~ + error[E0408]: variable `CONST1` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:31:23 | @@ -68,19 +81,6 @@ note: you might have meant to match on constant `m::CONST1`, which exists but is LL | const CONST1: usize = 10; | ^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible -error[E0408]: variable `Const2` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:31:9 - | -LL | (CONST1, _) | (_, Const2) => () - | ^^^^^^^^^^^ ------ variable not in all patterns - | | - | pattern doesn't bind `Const2` - | -help: if you meant to match on constant `m::Const2`, use the full path in the pattern - | -LL | (CONST1, _) | (_, m::Const2) => () - | ~~~~~~~~~ - error[E0308]: mismatched types --> $DIR/resolve-inconsistent-names.rs:19:19 | diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr index 81211b20a0135..500080832111b 100644 --- a/tests/ui/span/issue-39698.stderr +++ b/tests/ui/span/issue-39698.stderr @@ -1,3 +1,13 @@ +error[E0408]: variable `b` is not bound in all patterns + --> $DIR/issue-39698.rs:10:9 + | +LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + | ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b` + | | | | + | | | pattern doesn't bind `b` + | | variable not in all patterns + | pattern doesn't bind `b` + error[E0408]: variable `c` is not bound in all patterns --> $DIR/issue-39698.rs:10:9 | @@ -8,16 +18,6 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | pattern doesn't bind `c` | pattern doesn't bind `c` -error[E0408]: variable `d` is not bound in all patterns - --> $DIR/issue-39698.rs:10:37 - | -LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } - | - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d` - | | | | - | | | pattern doesn't bind `d` - | | variable not in all patterns - | variable not in all patterns - error[E0408]: variable `a` is not bound in all patterns --> $DIR/issue-39698.rs:10:23 | @@ -28,15 +28,15 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | pattern doesn't bind `a` | variable not in all patterns -error[E0408]: variable `b` is not bound in all patterns - --> $DIR/issue-39698.rs:10:9 +error[E0408]: variable `d` is not bound in all patterns + --> $DIR/issue-39698.rs:10:37 | LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } - | ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b` - | | | | - | | | pattern doesn't bind `b` - | | variable not in all patterns - | pattern doesn't bind `b` + | - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d` + | | | | + | | | pattern doesn't bind `d` + | | variable not in all patterns + | variable not in all patterns error: aborting due to 4 previous errors