From 1eaeaaf08b7135fd8d41339b90fdb6d189c89d69 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Sun, 7 Jan 2024 21:16:22 -0800 Subject: [PATCH 01/35] Add FileCheck for array_index.rs, boolean_identities.rs and cast.rs --- tests/mir-opt/dataflow-const-prop/array_index.rs | 12 +++++++++++- .../dataflow-const-prop/boolean_identities.rs | 5 ++++- tests/mir-opt/dataflow-const-prop/cast.rs | 8 +++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/array_index.rs b/tests/mir-opt/dataflow-const-prop/array_index.rs index 3d420f930076d..42c99df969e37 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/array_index.rs @@ -1,9 +1,19 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR array_index.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main() -> () { fn main() { + // CHECK: let mut [[array_lit:_.*]]: [u32; 4]; + // CHECK: debug x => [[x:_.*]]; + let x: u32 = [0, 1, 2, 3][2]; + // CHECK: bb{{[0-9]+}}: { + // CHECK: [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; + // CHECK: [[index:_.*]] = const 2_usize; + // CHECK: bb{{[0-9]+}}: { + // CHECK-NOT: [[x]] = [[array_lit]][[[index]]]; + // CHECK: [[x]] = [[array_lit]][2 of 3]; } diff --git a/tests/mir-opt/dataflow-const-prop/boolean_identities.rs b/tests/mir-opt/dataflow-const-prop/boolean_identities.rs index 2605c7019e6f4..93e9b8d52fc2e 100644 --- a/tests/mir-opt/dataflow-const-prop/boolean_identities.rs +++ b/tests/mir-opt/dataflow-const-prop/boolean_identities.rs @@ -1,11 +1,14 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR boolean_identities.test.DataflowConstProp.diff + +// CHECK-LABEL: fn test( pub fn test(x: bool, y: bool) -> bool { (y | true) & (x & false) + // CHECK: _0 = const false; } +// CHECK-LABEL: fn main( fn main() { test(true, false); } diff --git a/tests/mir-opt/dataflow-const-prop/cast.rs b/tests/mir-opt/dataflow-const-prop/cast.rs index c87872609dcf7..298ff49803936 100644 --- a/tests/mir-opt/dataflow-const-prop/cast.rs +++ b/tests/mir-opt/dataflow-const-prop/cast.rs @@ -1,8 +1,14 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR cast.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + + // CHECK: [[a]] = const 257_i32; let a = 257; + // CHECK: [[b]] = const 2_u8; let b = a as u8 + 1; } From e05c779ee30fc7d2bdbb41ae95dd7e5b7d404621 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Sun, 7 Jan 2024 21:16:55 -0800 Subject: [PATCH 02/35] Add FileCheck for checked.rs and default_boxed_slice.rs. --- tests/mir-opt/dataflow-const-prop/checked.rs | 17 ++++++++++++++++- .../dataflow-const-prop/default_boxed_slice.rs | 13 ++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/checked.rs b/tests/mir-opt/dataflow-const-prop/checked.rs index f7fac8890a057..7350e5fb3d83a 100644 --- a/tests/mir-opt/dataflow-const-prop/checked.rs +++ b/tests/mir-opt/dataflow-const-prop/checked.rs @@ -1,15 +1,30 @@ -// skip-filecheck // unit-test: DataflowConstProp // compile-flags: -Coverflow-checks=on // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR checked.main.DataflowConstProp.diff #[allow(arithmetic_overflow)] + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK: debug c => [[c:_.*]]; + // CHECK: debug d => [[d:_.*]]; + // CHECK: debug e => [[e:_.*]]; + + // CHECK: [[a]] = const 1_i32; let a = 1; + + // CHECK: [[b]] = const 2_i32; let b = 2; + + // CHECK: [[c]] = const 3_i32; let c = a + b; + // CHECK: [[d]] = const _; let d = i32::MAX; + + // CHECK: [[e]] = const i32::MIN; let e = d + 1; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs index 8006bd510e150..5917403450356 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs @@ -1,4 +1,3 @@ -// skip-filecheck // unit-test: DataflowConstProp // compile-flags: -Zmir-enable-passes=+GVN,+Inline // ignore-debug assertions change the output MIR @@ -11,8 +10,20 @@ struct A { // EMIT_MIR default_boxed_slice.main.GVN.diff // EMIT_MIR default_boxed_slice.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { // ConstProp will create a constant of type `Box<[bool]>`. // Verify that `DataflowConstProp` does not ICE trying to dereference it directly. + + // CHECK: debug a => [[a:_.*]]; + // CHECK: scope {{[0-9]+}} (inlined as Default>::default) { + // CHECK: scope {{[0-9]+}} (inlined Unique::<[bool; 0]>::dangling) { + // CHECK: scope {{[0-9]+}} (inlined NonNull::<[bool; 0]>::dangling) { + // We may check other inlined functions as well... + + // CHECK: bb{{[0-9]+}}: { + // CHECK: [[box_obj:_.*]] = Box::<[bool]>(_3, const std::alloc::Global); + // CHECK: [[a]] = A { foo: move [[box_obj]] }; let a: A = A { foo: Box::default() }; } From 33e5d851a923ab46544d2cda70f80a59e4c1398c Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Sun, 7 Jan 2024 22:03:42 -0800 Subject: [PATCH 03/35] Add FileCheck for enum.rs --- ...enum.constant.DataflowConstProp.64bit.diff | 4 +- ...enum.multiple.DataflowConstProp.32bit.diff | 2 +- ...enum.multiple.DataflowConstProp.64bit.diff | 2 +- tests/mir-opt/dataflow-const-prop/enum.rs | 72 ++++++++++++++++--- .../enum.simple.DataflowConstProp.32bit.diff | 4 +- .../enum.simple.DataflowConstProp.64bit.diff | 4 +- .../enum.statics.DataflowConstProp.32bit.diff | 16 ++--- .../enum.statics.DataflowConstProp.64bit.diff | 16 ++--- 8 files changed, 86 insertions(+), 34 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff index 07ac5b72e244c..f50a763ef9a05 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff @@ -14,10 +14,10 @@ debug x => _2; } scope 3 { - debug x => _4; + debug x1 => _4; } scope 4 { - debug x => _5; + debug x2 => _5; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff index 775325c4d0626..6bf702b856815 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff @@ -14,7 +14,7 @@ let _6: u8; let _8: u8; scope 2 { - debug x => _6; + debug x2 => _6; let _9: u8; scope 4 { debug y => _9; diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff index 775325c4d0626..6bf702b856815 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff @@ -14,7 +14,7 @@ let _6: u8; let _8: u8; scope 2 { - debug x => _6; + debug x2 => _6; let _9: u8; scope 4 { debug y => _9; diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index e35c0e6e85bed..f33e424034440 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -1,4 +1,3 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_BIT_WIDTH @@ -13,27 +12,66 @@ enum E { } // EMIT_MIR enum.simple.DataflowConstProp.diff + +// CHECK-LABEL: fn simple( fn simple() { + // CHECK: debug e => [[e:_.*]]; + // CHECK: debug x => [[x:_.*]]; + // CHECK: [[e]] = const E::V1(0_i32); let e = E::V1(0); - let x = match e { E::V1(x) => x, E::V2(x) => x }; + + // CHECK: switchInt(const 0_isize) -> [0: bb[[target_bb:[0-9]+]], 1: bb1, otherwise: bb2]; + // CHECK: bb[[target_bb]]: { + // CHECK: [[x]] = const 0_i32; + let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; } // EMIT_MIR enum.constant.DataflowConstProp.diff + +// CHECK-LABEL: fn constant( fn constant() { + // CHECK: debug e => [[e:_.*]]; + // CHECK: debug x => [[x:_.*]]; const C: E = E::V1(0); + + // CHECK: [[e]] = const _; let e = C; - let x = match e { E::V1(x) => x, E::V2(x) => x }; + // CHECK: switchInt(const 0_isize) -> [0: bb[[target_bb:[0-9]+]], 1: bb1, otherwise: bb2]; + // CHECK: bb[[target_bb]]: { + // CHECK: [[x]] = const 0_i32; + let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; } // EMIT_MIR enum.statics.DataflowConstProp.diff + +// CHECK-LABEL: fn statics( fn statics() { + // CHECK: debug e1 => [[e1:_.*]]; + // CHECK: debug x1 => [[x1:_.*]]; + // CHECK: debug e2 => [[e2:_.*]]; + // CHECK: debug x2 => [[x2:_.*]]; + static C: E = E::V1(0); - let e = C; - let x = match e { E::V1(x) => x, E::V2(x) => x }; + + // CHECK: [[e1]] = const E::V1(0_i32); + let e1 = C; + // CHECK: switchInt(const 0_isize) -> [0: bb[[target_bb1:[0-9]+]], 1: bb1, otherwise: bb2]; + // CHECK: bb[[target_bb]]: { + // CHECK: [[x1]] = const 0_i32; + let x1 = match e1 { E::V1(x11) => x11, E::V2(x12) => x12 }; static RC: &E = &E::V2(4); - let e = RC; - let x = match e { E::V1(x) => x, E::V2(x) => x }; + + // CHECK: [[t:_.*]] = const {alloc2: &&E}; + // CHECK: [[e2]] = (*[[t]]); + let e2 = RC; + // CHECK: switchInt(move _{{[0-9]+}}) -> [0: bb{{[0-9]+}}, 1: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}]; + // FIXME: add checks for x2. Currently, their MIRs are not symmetric in the two + // switch branches. + // One is `_9 = &(*_12) and another is `_9 = _11`. It is different from what we can + // get by printing MIR directly. It is better to check if there are any bugs in the + // MIR passes around this stage. + let x2 = match e2 { E::V1(x21) => x21, E::V2(x22) => x22 }; } #[rustc_layout_scalar_valid_range_start(1)] @@ -41,6 +79,8 @@ fn statics() { struct NonZeroUsize(usize); // EMIT_MIR enum.mutate_discriminant.DataflowConstProp.diff + +// CHECK-LABEL: fn mutate_discriminant( #[custom_mir(dialect = "runtime", phase = "post-cleanup")] fn mutate_discriminant() -> u8 { mir!( @@ -50,7 +90,11 @@ fn mutate_discriminant() -> u8 { // This assignment overwrites the niche in which the discriminant is stored. place!(Field(Field(Variant(x, 1), 0), 0)) = 0_usize; // So we cannot know the value of this discriminant. + + // CHECK: [[a:_.*]] = discriminant(_{{[0-9]*}}); let a = Discriminant(x); + + // CHECK: switchInt([[a]]) -> [0: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}]; match a { 0 => bb1, _ => bad, @@ -68,18 +112,26 @@ fn mutate_discriminant() -> u8 { } // EMIT_MIR enum.multiple.DataflowConstProp.diff +// CHECK-LABEL: fn multiple( fn multiple(x: bool, i: u8) { + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug e => [[e:_.*]]; + // CHECK: debug x2 => [[x2:_.*]]; let e = if x { + // CHECK: [[e]] = Option::::Some(move _{{[0-9]+}}); Some(i) } else { + // CHECK: [[e]] = Option::::None; None }; // The dataflow state must have: // discriminant(e) => Top // (e as Some).0 => Top - let x = match e { Some(i) => i, None => 0 }; - // Therefore, `x` should be `Top` here, and no replacement shall happen. - let y = x; + // CHECK: [[x2]] = const 0_u8; + // CHECK: [[x2]] = _{{[0-9]+}} + let x2 = match e { Some(i) => i, None => 0 }; + // Therefore, `x2` should be `Top` here, and no replacement shall happen. + let y = x2; } fn main() { diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff index 798b0c041b4ec..b31f98460e45b 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff @@ -14,10 +14,10 @@ debug x => _2; } scope 3 { - debug x => _4; + debug x1 => _4; } scope 4 { - debug x => _5; + debug x2 => _5; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff index 798b0c041b4ec..b31f98460e45b 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff @@ -14,10 +14,10 @@ debug x => _2; } scope 3 { - debug x => _4; + debug x1 => _4; } scope 4 { - debug x => _5; + debug x2 => _5; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff index 053981abea3ec..44e8d39cca333 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff @@ -9,34 +9,34 @@ let mut _8: &&E; let mut _10: isize; scope 1 { - debug e => _1; + debug e1 => _1; let _3: i32; let _5: i32; let _6: i32; scope 2 { - debug x => _3; + debug x1 => _3; let _7: &E; scope 5 { - debug e => _7; + debug e2 => _7; let _9: &i32; let _11: &i32; let _12: &i32; scope 6 { - debug x => _9; + debug x2 => _9; } scope 7 { - debug x => _11; + debug x21 => _11; } scope 8 { - debug x => _12; + debug x22 => _12; } } } scope 3 { - debug x => _5; + debug x11 => _5; } scope 4 { - debug x => _6; + debug x12 => _6; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff index d862bd93ff577..ac4ca086d0fed 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff @@ -9,34 +9,34 @@ let mut _8: &&E; let mut _10: isize; scope 1 { - debug e => _1; + debug e1 => _1; let _3: i32; let _5: i32; let _6: i32; scope 2 { - debug x => _3; + debug x1 => _3; let _7: &E; scope 5 { - debug e => _7; + debug e2 => _7; let _9: &i32; let _11: &i32; let _12: &i32; scope 6 { - debug x => _9; + debug x2 => _9; } scope 7 { - debug x => _11; + debug x21 => _11; } scope 8 { - debug x => _12; + debug x22 => _12; } } } scope 3 { - debug x => _5; + debug x11 => _5; } scope 4 { - debug x => _6; + debug x12 => _6; } } From 24aefa0e5d134526c8e29c5603dcb4d42637968a Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Mon, 8 Jan 2024 16:58:58 -0800 Subject: [PATCH 04/35] Add FileCheck for if.rs, inherit_overflow.rs, issue_81605.rs --- tests/mir-opt/dataflow-const-prop/if.rs | 18 +++++++++++++++++- .../dataflow-const-prop/inherit_overflow.rs | 5 ++++- .../mir-opt/dataflow-const-prop/issue_81605.rs | 5 ++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/if.rs b/tests/mir-opt/dataflow-const-prop/if.rs index 72aabbccf56c8..28e0ee9c622f5 100644 --- a/tests/mir-opt/dataflow-const-prop/if.rs +++ b/tests/mir-opt/dataflow-const-prop/if.rs @@ -1,12 +1,28 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR if.main.DataflowConstProp.diff +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug b => [[b:_.*]]; + // CHECK: debug c => [[c:_.*]]; + // CHECK: debug d => [[d:_.*]]; + // CHECK: debug e => [[e:_.*]]; + let a = 1; + + // CHECK: switchInt(const true) -> [0: {{bb[0-9]+}}, otherwise: [[bb_first_true:bb[0-9]+]]]; + // CHECK: [[bb_first_true]]: { + // CHECK: [[b]] = const 2_i32; let b = if a == 1 { 2 } else { 3 }; + + // CHECK: [[c]] = const 3_i32; let c = b + 1; + // CHECK: switchInt(const true) -> [0: {{bb[0-9]+}}, otherwise: [[bb_second_true:bb[0-9]+]]]; + // CHECK: [[bb_second_true]]: { + // CHECK: [[d]] = const 1_i32; let d = if a == 1 { a } else { a + 1 }; + + // CHECK: [[e]] = const 2_i32; let e = d + 1; } diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs index 664cbcb2c259f..0a2774c782009 100644 --- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs @@ -1,11 +1,14 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp // compile-flags: -Zmir-enable-passes=+Inline // EMIT_MIR inherit_overflow.main.DataflowConstProp.diff +// CHECK-LABEL: fn main( fn main() { // After inlining, this will contain a `CheckedBinaryOp`. // Propagating the overflow is ok as codegen will just skip emitting the panic. + + // CHECK: {{_.*}} = const (0_u8, true); + // CHECK-LABEL: assert(!const true, let _ = ::add(255, 1); } diff --git a/tests/mir-opt/dataflow-const-prop/issue_81605.rs b/tests/mir-opt/dataflow-const-prop/issue_81605.rs index 7c5eceb8a2b68..e8a00c72eb66b 100644 --- a/tests/mir-opt/dataflow-const-prop/issue_81605.rs +++ b/tests/mir-opt/dataflow-const-prop/issue_81605.rs @@ -1,9 +1,12 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR issue_81605.f.DataflowConstProp.diff + +// CHECK-LABEL: fn f fn f() -> usize { + // CHECK: switchInt(const true) -> [0: {{bb[0-9]+}}, otherwise: {{bb[0-9]+}}]; 1 + if true { 1 } else { 2 } + // CHECK: _0 = const 2_usize; } fn main() { From 9452d7ed1acd62c44dbec775d42f41b508c572bf Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Mon, 8 Jan 2024 20:18:59 -0800 Subject: [PATCH 05/35] Add FileCheck to 3 tests: large_array_index, mult_by_zero, and offset_of --- .../dataflow-const-prop/large_array_index.rs | 10 ++++++- .../dataflow-const-prop/mult_by_zero.rs | 3 +- .../mir-opt/dataflow-const-prop/offset_of.rs | 29 ++++++++++++++++++- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.rs b/tests/mir-opt/dataflow-const-prop/large_array_index.rs index d611a54ba71a2..6b8a0248d19bc 100644 --- a/tests/mir-opt/dataflow-const-prop/large_array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/large_array_index.rs @@ -1,10 +1,18 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR large_array_index.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main fn main() { // check that we don't propagate this, because it's too large + + // CHECK: debug x => [[x:_.*]]; + // CHECK: [[array_lit:_.*]] = [const 0_u8; 5000]; + // CHECK: {{_.*}} = const 5000_usize; + // CHECK: {{_.*}} = const true; + // CHECK-LABEL: assert(const true + // CHECK: [[x]] = [[array_lit]][2 of 3]; let x: u8 = [0_u8; 5000][2]; } diff --git a/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs b/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs index 16a45c8e9fb59..c7e05579e4005 100644 --- a/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs +++ b/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs @@ -1,9 +1,10 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR mult_by_zero.test.DataflowConstProp.diff +// CHECK-LABEL: fn test fn test(x : i32) -> i32 { x * 0 + // CHECK: _0 = const 0_i32; } fn main() { diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.rs b/tests/mir-opt/dataflow-const-prop/offset_of.rs index e71b3f59ecab3..a2032ea996edd 100644 --- a/tests/mir-opt/dataflow-const-prop/offset_of.rs +++ b/tests/mir-opt/dataflow-const-prop/offset_of.rs @@ -1,4 +1,3 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_PANIC_STRATEGY @@ -29,18 +28,46 @@ struct Delta { } // EMIT_MIR offset_of.concrete.DataflowConstProp.diff + +// CHECK-LABEL: fn concrete fn concrete() { + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug y => [[y:_.*]]; + // CHECK: debug z0 => [[z0:_.*]]; + // CHECK: debug z1 => [[z1:_.*]]; + + // CHECK: [[x]] = must_use::(const 4_usize) -> [return: {{bb[0-9]+}}, unwind continue]; let x = offset_of!(Alpha, x); + + // CHECK: [[y]] = must_use::(const 0_usize) -> [return: {{bb[0-9]+}}, unwind continue]; let y = offset_of!(Alpha, y); + + // CHECK: [[z0]] = must_use::(const 2_usize) -> [return: {{bb[0-9]+}}, unwind continue]; let z0 = offset_of!(Alpha, z.0); + + // CHECK: [[z1]] = must_use::(const 3_usize) -> [return: {{bb[0-9]+}}, unwind continue]; let z1 = offset_of!(Alpha, z.1); } // EMIT_MIR offset_of.generic.DataflowConstProp.diff + +// CHECK-LABEL: generic fn generic() { + // CHECK: debug gx => [[gx:_.*]]; + // CHECK: debug gy => [[gy:_.*]]; + // CHECK: debug dx => [[dx:_.*]]; + // CHECK: debug dy => [[dy:_.*]]; + + // CHECK: [[gx]] = must_use::(move {{_[0-9]+}}) -> [return: {{bb[0-9]+}}, unwind continue]; let gx = offset_of!(Gamma, x); + + // CHECK: [[gy]] = must_use::(move {{_[0-9]+}}) -> [return: {{bb[0-9]+}}, unwind continue]; let gy = offset_of!(Gamma, y); + + // CHECK: [[dx]] = must_use::(const 0_usize) -> [return: {{bb[0-9]+}}, unwind continue]; let dx = offset_of!(Delta, x); + + // CHECK: [[dy]] = must_use::(const 2_usize) -> [return: {{bb[0-9]+}}, unwind continue]; let dy = offset_of!(Delta, y); } From e9152e2b6c95aad0f3c89af8b0f98a0cbf4f45c7 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Mon, 8 Jan 2024 20:19:59 -0800 Subject: [PATCH 06/35] Add FileCheck to 3 tests: ref_without_sb, repeat, repr_transparent --- tests/mir-opt/dataflow-const-prop/ref_without_sb.rs | 11 ++++++++++- tests/mir-opt/dataflow-const-prop/repeat.rs | 10 +++++++++- tests/mir-opt/dataflow-const-prop/repr_transparent.rs | 9 ++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs index 2851c0590ad5f..fb66cda38ddbd 100644 --- a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs +++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp @@ -9,11 +8,21 @@ fn escape(x: &T) {} fn some_function() {} // EMIT_MIR ref_without_sb.main.DataflowConstProp.diff +// CHECK-LABEL: fn main fn main() { + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + let mut a = 0; + + // CHECK: {{_[0-9]+}} = escape::(move {{_[0-9]+}}) -> [return: {{bb[0-9]+}}, unwind continue]; escape(&a); a = 1; + + // CHECK: {{_[0-9]+}} = some_function() -> [return: {{bb[0-9]+}}, unwind continue]; some_function(); // This should currently not be propagated. + + // CHECK: [[b]] = [[a]]; let b = a; } diff --git a/tests/mir-opt/dataflow-const-prop/repeat.rs b/tests/mir-opt/dataflow-const-prop/repeat.rs index b824481948116..5d1c1a3edb695 100644 --- a/tests/mir-opt/dataflow-const-prop/repeat.rs +++ b/tests/mir-opt/dataflow-const-prop/repeat.rs @@ -1,9 +1,17 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR repeat.main.DataflowConstProp.diff +// CHECK-LABEL: fn main fn main() { + // CHECK: debug x => [[x:_.*]]; + + // CHECK: {{_[0-9]+}} = const 8_usize; + // CHECK: {{_[0-9]+}} = const true; + // CHECK-LABEL: assert(const true + + // CHECK: {{_[0-9]+}} = {{_[0-9]+}}[2 of 3]; + // CHECK: [[x]] = Add(move {{_[0-9]+}}, const 0_u32); let x: u32 = [42; 8][2] + 0; } diff --git a/tests/mir-opt/dataflow-const-prop/repr_transparent.rs b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs index 8cbed6fbb624d..d007301e568b1 100644 --- a/tests/mir-opt/dataflow-const-prop/repr_transparent.rs +++ b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs @@ -1,4 +1,3 @@ -// skip-filecheck // unit-test: DataflowConstProp // The struct has scalar ABI, but is not a scalar type. @@ -7,7 +6,15 @@ struct I32(i32); // EMIT_MIR repr_transparent.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main fn main() { + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug y => [[y:_.*]]; + + // CHECK: [[x]] = const I32(0_i32); let x = I32(0); + + // CHECK: [[y]] = const I32(0_i32); let y = I32(x.0 + x.0); } From 3ab1d5d4506924b6d020c8edf539d2be6b7bb9e9 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Mon, 8 Jan 2024 20:20:27 -0800 Subject: [PATCH 07/35] Add FileCheck to 3 tests: self_assign_add, self_assign, and sibling_ptr --- tests/mir-opt/dataflow-const-prop/self_assign.rs | 15 ++++++++++++++- .../dataflow-const-prop/self_assign_add.rs | 8 +++++++- tests/mir-opt/dataflow-const-prop/sibling_ptr.rs | 7 ++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/self_assign.rs b/tests/mir-opt/dataflow-const-prop/self_assign.rs index c5866c4a9fd98..7d58b972d655b 100644 --- a/tests/mir-opt/dataflow-const-prop/self_assign.rs +++ b/tests/mir-opt/dataflow-const-prop/self_assign.rs @@ -1,13 +1,26 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR self_assign.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main fn main() { + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + let mut a = 0; + + // CHECK: [[a]] = Add(move {{_[0-9]+}}, const 1_i32); a = a + 1; + + // CHECK: [[a]] = move {{_[0-9]+}}; a = a; + // CHECK: [[b]] = &[[a]]; let mut b = &a; + + // CHECK: [[b]] = move {{_[0-9]+}}; b = b; + + // CHECK: [[a]] = move {{_[0-9]+}}; a = *b; } diff --git a/tests/mir-opt/dataflow-const-prop/self_assign_add.rs b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs index cfe1458e44be7..09be3865d60b3 100644 --- a/tests/mir-opt/dataflow-const-prop/self_assign_add.rs +++ b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs @@ -1,9 +1,15 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR self_assign_add.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main fn main() { + // CHECK: debug a => [[a:_.*]]; let mut a = 0; + + // CHECK: [[a]] = const 1_i32; a += 1; + + // CHECK: [[a]] = const 2_i32; a += 1; } diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs index 68aff528695d5..6e39e39839410 100644 --- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // This attempts to modify `x.1` via a pointer derived from `addr_of_mut!(x.0)`. // According to Miri, that is UB. However, T-opsem has not finalized that @@ -10,11 +9,17 @@ // unit-test: DataflowConstProp // EMIT_MIR sibling_ptr.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main fn main() { + // CHECK: debug x1 => [[x1:_[0-9]+]]; + let mut x: (u8, u8) = (0, 0); unsafe { let p = std::ptr::addr_of_mut!(x.0); *p.add(1) = 1; } + + // CHECK: [[x1]] = ({{_[0-9]+}}.1: u8); let x1 = x.1; // should not be propagated } From d765e3ae1faf4786b56da542c9dc5fbfc18162d8 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Mon, 8 Jan 2024 20:20:53 -0800 Subject: [PATCH 08/35] Add FileCheck to slice_len.rs --- tests/mir-opt/dataflow-const-prop/slice_len.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.rs b/tests/mir-opt/dataflow-const-prop/slice_len.rs index 86266ef5d4e60..cd63980949638 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.rs +++ b/tests/mir-opt/dataflow-const-prop/slice_len.rs @@ -1,13 +1,23 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp // compile-flags: -Zmir-enable-passes=+InstSimplify // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR slice_len.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main fn main() { + // CHECK: debug local => [[local:_[0-9]+]]; + // CHECK: debug constant => [[constant:_[0-9]+]]; + + // CHECK: {{_[0-9]+}} = const 3_usize; + // CHECK: {{_[0-9]+}} = const true; + + // CHECK: [[local]] = (*{{_[0-9]+}})[1 of 2]; let local = (&[1u32, 2, 3] as &[u32])[1]; const SLICE: &[u32] = &[1, 2, 3]; + + // CHECK: [[constant]] = (*{{_[0-9]+}})[1 of 2]; let constant = SLICE[1]; } From 732f6a1303c4e3f9a354221e76e065571b2f1e37 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Mon, 8 Jan 2024 20:21:06 -0800 Subject: [PATCH 09/35] Add FileCheck to struct.rs --- .../struct.main.DataflowConstProp.32bit.diff | 24 ++++---- .../struct.main.DataflowConstProp.64bit.diff | 24 ++++---- tests/mir-opt/dataflow-const-prop/struct.rs | 55 ++++++++++++++++--- 3 files changed, 72 insertions(+), 31 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff index 0f461f515fdd0..c486281d6f8d7 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff @@ -37,16 +37,16 @@ let _8: std::option::Option; let _9: &[f32]; scope 4 { - debug a => _7; - debug b => _8; - debug c => _9; + debug a1 => _7; + debug b1 => _8; + debug c1 => _9; let _11: f32; let _12: std::option::Option; let _13: &[f32]; scope 5 { - debug a => _11; - debug b => _12; - debug c => _13; + debug a2 => _11; + debug b2 => _12; + debug c2 => _13; let _15: SmallStruct; scope 6 { debug ss => _15; @@ -54,16 +54,16 @@ let _20: std::option::Option; let _21: &[f32]; scope 7 { - debug a => _19; - debug b => _20; - debug c => _21; + debug a3 => _19; + debug b3 => _20; + debug c3 => _21; let _23: f32; let _24: std::option::Option; let _25: &[f32]; scope 8 { - debug a => _23; - debug b => _24; - debug c => _25; + debug a4 => _23; + debug b4 => _24; + debug c4 => _25; let _27: BigStruct; scope 9 { debug bs => _27; diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff index 3c40ec8bfb450..7ea53d157334d 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff @@ -37,16 +37,16 @@ let _8: std::option::Option; let _9: &[f32]; scope 4 { - debug a => _7; - debug b => _8; - debug c => _9; + debug a1 => _7; + debug b1 => _8; + debug c1 => _9; let _11: f32; let _12: std::option::Option; let _13: &[f32]; scope 5 { - debug a => _11; - debug b => _12; - debug c => _13; + debug a2 => _11; + debug b2 => _12; + debug c2 => _13; let _15: SmallStruct; scope 6 { debug ss => _15; @@ -54,16 +54,16 @@ let _20: std::option::Option; let _21: &[f32]; scope 7 { - debug a => _19; - debug b => _20; - debug c => _21; + debug a3 => _19; + debug b3 => _20; + debug c3 => _21; let _23: f32; let _24: std::option::Option; let _25: &[f32]; scope 8 { - debug a => _23; - debug b => _24; - debug c => _25; + debug a4 => _23; + debug b4 => _24; + debug c4 => _25; let _27: BigStruct; scope 9 { debug bs => _27; diff --git a/tests/mir-opt/dataflow-const-prop/struct.rs b/tests/mir-opt/dataflow-const-prop/struct.rs index 043981a295484..4eec15a7f1630 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.rs +++ b/tests/mir-opt/dataflow-const-prop/struct.rs @@ -1,4 +1,3 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_BIT_WIDTH @@ -12,27 +11,69 @@ struct SmallStruct(f32, Option, &'static [f32]); struct BigStruct(f32, Option, &'static [f32]); // EMIT_MIR struct.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main fn main() { + // CHECK: debug s => [[s:_[0-9]+]]; + // CHECK: debug a => [[a:_[0-9]+]]; + // CHECK: debug b => [[b:_[0-9]+]]; + // CHECK: debug a1 => [[a1:_[0-9]+]]; + // CHECK: debug b1 => [[b1:_[0-9]+]]; + // CHECK: debug c1 => [[c1:_[0-9]+]]; + // CHECK: debug a2 => [[a2:_[0-9]+]]; + // CHECK: debug b2 => [[b2:_[0-9]+]]; + // CHECK: debug c2 => [[c2:_[0-9]+]]; + // CHECK: debug ss => [[ss:_[0-9]+]]; + // CHECK: debug a3 => [[a3:_[0-9]+]]; + // CHECK: debug b3 => [[b3:_[0-9]+]]; + // CHECK: debug c3 => [[c3:_[0-9]+]]; + // CHECK: debug a4 => [[a4:_[0-9]+]]; + // CHECK: debug b4 => [[b4:_[0-9]+]]; + // CHECK: debug c4 => [[c4:_[0-9]+]]; + // CHECK: debug bs => [[bs:_[0-9]+]]; + + // CHECK: [[s]] = const S(1_i32); let mut s = S(1); + + // CHECK: [[a]] = const 3_i32; let a = s.0 + 2; s.0 = 3; + + // CHECK: [[b]] = const 6_i32; let b = a + s.0; const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]); - let SmallStruct(a, b, c) = SMALL_VAL; + + // CHECK: [[a1]] = const 4f32; + // CHECK: [[b1]] = const Option::::Some(S(1_i32)); + // CHECK: [[c1]] = ({{_[0-9]+}}.2: &[f32]); + let SmallStruct(a1, b1, c1) = SMALL_VAL; static SMALL_STAT: &SmallStruct = &SmallStruct(9., None, &[13.]); - let SmallStruct(a, b, c) = *SMALL_STAT; - let ss = SmallStruct(a, b, c); + // CHECK: [[a2]] = const 9f32; + // CHECK: [[b2]] = ((*{{_[0-9]+}}).1: std::option::Option); + // CHECK: [[c2]] = ((*{{_[0-9]+}}).2: &[f32]); + let SmallStruct(a2, b2, c2) = *SMALL_STAT; + + // CHECK: [[ss]] = SmallStruct(const 9f32, move {{_[0-9]+}}, move {{_[0-9]+}}); + let ss = SmallStruct(a2, b2, c2); const BIG_VAL: BigStruct = BigStruct(25., None, &[]); - let BigStruct(a, b, c) = BIG_VAL; + + // CHECK: [[a3]] = const 25f32; + // CHECK: [[b3]] = ({{_[0-9]+}}.1: std::option::Option); + // CHECK: [[c3]] = ({{_[0-9]+}}.2: &[f32]); + let BigStruct(a3, b3, c3) = BIG_VAL; static BIG_STAT: &BigStruct = &BigStruct(82., Some(S(35)), &[45., 72.]); - let BigStruct(a, b, c) = *BIG_STAT; + // CHECK: [[a4]] = const 82f32; + // CHECK: [[b4]] = const Option::::Some(S(35_i32)); + // CHECK: [[c4]] = ((*{{_[0-9]+}}).2: &[f32]); + let BigStruct(a4, b4, c4) = *BIG_STAT; // We arbitrarily limit the size of synthetized values to 4 pointers. // `BigStruct` can be read, but we will keep a MIR aggregate for this. - let bs = BigStruct(a, b, c); + // CHECK: [[bs]] = BigStruct(const 82f32, const Option::::Some(S(35_i32)), move {{_[0-9]+}}); + let bs = BigStruct(a4, b4, c4); } From 1adda9a170085823f43672e60c19be29a4deb18f Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Mon, 8 Jan 2024 20:21:23 -0800 Subject: [PATCH 10/35] Add FileCheck to terminator.rs and tuple.rs --- tests/mir-opt/dataflow-const-prop/terminator.rs | 4 +++- tests/mir-opt/dataflow-const-prop/tuple.rs | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/terminator.rs b/tests/mir-opt/dataflow-const-prop/terminator.rs index 92a42f22c218f..985eddad26440 100644 --- a/tests/mir-opt/dataflow-const-prop/terminator.rs +++ b/tests/mir-opt/dataflow-const-prop/terminator.rs @@ -1,12 +1,14 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp fn foo(n: i32) {} // EMIT_MIR terminator.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main fn main() { let a = 1; // Checks that we propagate into terminators. + // CHECK: {{_[0-9]+}} = foo(const 2_i32) -> [return: {{bb[0-9]+}}, unwind continue]; foo(a + 1); } diff --git a/tests/mir-opt/dataflow-const-prop/tuple.rs b/tests/mir-opt/dataflow-const-prop/tuple.rs index bb706eafe8885..bd5adeda8b3dc 100644 --- a/tests/mir-opt/dataflow-const-prop/tuple.rs +++ b/tests/mir-opt/dataflow-const-prop/tuple.rs @@ -1,13 +1,27 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR tuple.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main fn main() { + // CHECK: debug a => [[a:_[0-9]+]]; + // CHECK: debug b => [[b:_[0-9]+]]; + // CHECK: debug c => [[c:_[0-9]+]]; + // CHECK: debug d => [[d:_[0-9]+]]; + + // CHECK: [[a]] = const (1_i32, 2_i32); let mut a = (1, 2); + + // CHECK: [[b]] = const 6_i32; let b = a.0 + a.1 + 3; + + // CHECK: [[a]] = const (2_i32, 3_i32); a = (2, 3); + + // CHECK: [[c]] = const 11_i32; let c = a.0 + a.1 + b; + // CHECK: [[d]] = (const 6_i32, const (2_i32, 3_i32), const 11_i32); let d = (b, a, c); } From 7135168d0874ee5e0485bb31d89ab69966a48337 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Sun, 7 Jan 2024 22:03:42 -0800 Subject: [PATCH 11/35] Add FileCheck for enum.rs --- .../enum.constant.DataflowConstProp.32bit.diff | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff index 07ac5b72e244c..f50a763ef9a05 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff @@ -14,10 +14,10 @@ debug x => _2; } scope 3 { - debug x => _4; + debug x1 => _4; } scope 4 { - debug x => _5; + debug x2 => _5; } } From d63f10b7addc4f5c5528b76cedb41433a275eed3 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Thu, 11 Jan 2024 23:22:33 -0800 Subject: [PATCH 12/35] resolve code reviews --- .../dataflow-const-prop/array_index.rs | 7 +-- .../dataflow-const-prop/boolean_identities.rs | 4 ++ tests/mir-opt/dataflow-const-prop/checked.rs | 2 + .../default_boxed_slice.rs | 5 +- tests/mir-opt/dataflow-const-prop/enum.rs | 23 ++++---- tests/mir-opt/dataflow-const-prop/if.rs | 6 +-- .../dataflow-const-prop/issue_81605.rs | 10 +++- .../dataflow-const-prop/large_array_index.rs | 2 +- .../dataflow-const-prop/mult_by_zero.rs | 2 +- .../mir-opt/dataflow-const-prop/offset_of.rs | 20 +++---- .../dataflow-const-prop/ref_without_sb.rs | 8 +-- tests/mir-opt/dataflow-const-prop/repeat.rs | 14 +++-- .../dataflow-const-prop/repr_transparent.rs | 2 +- .../dataflow-const-prop/self_assign.rs | 10 ++-- .../dataflow-const-prop/self_assign_add.rs | 2 +- .../dataflow-const-prop/sibling_ptr.rs | 6 +-- .../mir-opt/dataflow-const-prop/slice_len.rs | 25 ++++++--- tests/mir-opt/dataflow-const-prop/struct.rs | 52 +++++++++---------- .../mir-opt/dataflow-const-prop/terminator.rs | 4 +- tests/mir-opt/dataflow-const-prop/tuple.rs | 10 ++-- 20 files changed, 118 insertions(+), 96 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/array_index.rs b/tests/mir-opt/dataflow-const-prop/array_index.rs index 42c99df969e37..4b070e1d6d6f6 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/array_index.rs @@ -10,10 +10,7 @@ fn main() { // CHECK: debug x => [[x:_.*]]; let x: u32 = [0, 1, 2, 3][2]; - // CHECK: bb{{[0-9]+}}: { - // CHECK: [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; - // CHECK: [[index:_.*]] = const 2_usize; - // CHECK: bb{{[0-9]+}}: { - // CHECK-NOT: [[x]] = [[array_lit]][[[index]]]; + // CHECK: [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; + // CHECK-LABEL: assert(const true, // CHECK: [[x]] = [[array_lit]][2 of 3]; } diff --git a/tests/mir-opt/dataflow-const-prop/boolean_identities.rs b/tests/mir-opt/dataflow-const-prop/boolean_identities.rs index 93e9b8d52fc2e..c9be1d65b0302 100644 --- a/tests/mir-opt/dataflow-const-prop/boolean_identities.rs +++ b/tests/mir-opt/dataflow-const-prop/boolean_identities.rs @@ -4,8 +4,12 @@ // CHECK-LABEL: fn test( pub fn test(x: bool, y: bool) -> bool { + // CHECK-NOT: BitAnd( + // CHECK-NOT: BitOr( (y | true) & (x & false) // CHECK: _0 = const false; + // CHECK-NOT: BitAnd( + // CHECK-NOT: BitOr( } // CHECK-LABEL: fn main( diff --git a/tests/mir-opt/dataflow-const-prop/checked.rs b/tests/mir-opt/dataflow-const-prop/checked.rs index 7350e5fb3d83a..45331f91323e4 100644 --- a/tests/mir-opt/dataflow-const-prop/checked.rs +++ b/tests/mir-opt/dataflow-const-prop/checked.rs @@ -19,12 +19,14 @@ fn main() { // CHECK: [[b]] = const 2_i32; let b = 2; + // CHECK-LABEL: assert(!const false, // CHECK: [[c]] = const 3_i32; let c = a + b; // CHECK: [[d]] = const _; let d = i32::MAX; + // CHECK-LABEL: assert(!const true, // CHECK: [[e]] = const i32::MIN; let e = d + 1; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs index 5917403450356..b15809f2510ff 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs @@ -17,13 +17,10 @@ fn main() { // Verify that `DataflowConstProp` does not ICE trying to dereference it directly. // CHECK: debug a => [[a:_.*]]; - // CHECK: scope {{[0-9]+}} (inlined as Default>::default) { - // CHECK: scope {{[0-9]+}} (inlined Unique::<[bool; 0]>::dangling) { - // CHECK: scope {{[0-9]+}} (inlined NonNull::<[bool; 0]>::dangling) { // We may check other inlined functions as well... - // CHECK: bb{{[0-9]+}}: { // CHECK: [[box_obj:_.*]] = Box::<[bool]>(_3, const std::alloc::Global); // CHECK: [[a]] = A { foo: move [[box_obj]] }; + // FIXME: we do not have `const Box::<[bool]>` after constprop right now. let a: A = A { foo: Box::default() }; } diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index f33e424034440..26fdda2664a95 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -20,8 +20,8 @@ fn simple() { // CHECK: [[e]] = const E::V1(0_i32); let e = E::V1(0); - // CHECK: switchInt(const 0_isize) -> [0: bb[[target_bb:[0-9]+]], 1: bb1, otherwise: bb2]; - // CHECK: bb[[target_bb]]: { + // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2]; + // CHECK: [[target_bb]]: { // CHECK: [[x]] = const 0_i32; let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; } @@ -36,8 +36,8 @@ fn constant() { // CHECK: [[e]] = const _; let e = C; - // CHECK: switchInt(const 0_isize) -> [0: bb[[target_bb:[0-9]+]], 1: bb1, otherwise: bb2]; - // CHECK: bb[[target_bb]]: { + // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2]; + // CHECK: [[target_bb]]: { // CHECK: [[x]] = const 0_i32; let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; } @@ -55,8 +55,8 @@ fn statics() { // CHECK: [[e1]] = const E::V1(0_i32); let e1 = C; - // CHECK: switchInt(const 0_isize) -> [0: bb[[target_bb1:[0-9]+]], 1: bb1, otherwise: bb2]; - // CHECK: bb[[target_bb]]: { + // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2]; + // CHECK: [[target_bb]]: { // CHECK: [[x1]] = const 0_i32; let x1 = match e1 { E::V1(x11) => x11, E::V2(x12) => x12 }; @@ -65,7 +65,8 @@ fn statics() { // CHECK: [[t:_.*]] = const {alloc2: &&E}; // CHECK: [[e2]] = (*[[t]]); let e2 = RC; - // CHECK: switchInt(move _{{[0-9]+}}) -> [0: bb{{[0-9]+}}, 1: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}]; + + // CHECK: switchInt({{move _.*}}) -> {{.*}} // FIXME: add checks for x2. Currently, their MIRs are not symmetric in the two // switch branches. // One is `_9 = &(*_12) and another is `_9 = _11`. It is different from what we can @@ -91,10 +92,10 @@ fn mutate_discriminant() -> u8 { place!(Field(Field(Variant(x, 1), 0), 0)) = 0_usize; // So we cannot know the value of this discriminant. - // CHECK: [[a:_.*]] = discriminant(_{{[0-9]*}}); + // CHECK: [[a:_.*]] = discriminant({{_.*}}); let a = Discriminant(x); - // CHECK: switchInt([[a]]) -> [0: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}]; + // CHECK: switchInt([[a]]) -> [0: {{bb.*}}, otherwise: {{bb.*}}]; match a { 0 => bb1, _ => bad, @@ -118,7 +119,7 @@ fn multiple(x: bool, i: u8) { // CHECK: debug e => [[e:_.*]]; // CHECK: debug x2 => [[x2:_.*]]; let e = if x { - // CHECK: [[e]] = Option::::Some(move _{{[0-9]+}}); + // CHECK: [[e]] = Option::::Some(move {{_.*}}); Some(i) } else { // CHECK: [[e]] = Option::::None; @@ -128,7 +129,7 @@ fn multiple(x: bool, i: u8) { // discriminant(e) => Top // (e as Some).0 => Top // CHECK: [[x2]] = const 0_u8; - // CHECK: [[x2]] = _{{[0-9]+}} + // CHECK: [[x2]] = {{_.*}}; let x2 = match e { Some(i) => i, None => 0 }; // Therefore, `x2` should be `Top` here, and no replacement shall happen. let y = x2; diff --git a/tests/mir-opt/dataflow-const-prop/if.rs b/tests/mir-opt/dataflow-const-prop/if.rs index 28e0ee9c622f5..3400068baba2a 100644 --- a/tests/mir-opt/dataflow-const-prop/if.rs +++ b/tests/mir-opt/dataflow-const-prop/if.rs @@ -10,16 +10,14 @@ fn main() { let a = 1; - // CHECK: switchInt(const true) -> [0: {{bb[0-9]+}}, otherwise: [[bb_first_true:bb[0-9]+]]]; - // CHECK: [[bb_first_true]]: { + // CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}]; // CHECK: [[b]] = const 2_i32; let b = if a == 1 { 2 } else { 3 }; // CHECK: [[c]] = const 3_i32; let c = b + 1; - // CHECK: switchInt(const true) -> [0: {{bb[0-9]+}}, otherwise: [[bb_second_true:bb[0-9]+]]]; - // CHECK: [[bb_second_true]]: { + // CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}]; // CHECK: [[d]] = const 1_i32; let d = if a == 1 { a } else { a + 1 }; diff --git a/tests/mir-opt/dataflow-const-prop/issue_81605.rs b/tests/mir-opt/dataflow-const-prop/issue_81605.rs index e8a00c72eb66b..f13c364279d41 100644 --- a/tests/mir-opt/dataflow-const-prop/issue_81605.rs +++ b/tests/mir-opt/dataflow-const-prop/issue_81605.rs @@ -2,9 +2,15 @@ // EMIT_MIR issue_81605.f.DataflowConstProp.diff -// CHECK-LABEL: fn f +// Plese find the original issue [here](https://github.com/rust-lang/rust/issues/81605). +// This test program comes directly from the issue. Prior to this issue, +// the compiler cannot simplify the return value of `f` into 2. This was +// solved by adding a new MIR constant propagation based on dataflow +// analysis in [#101168](https://github.com/rust-lang/rust/pull/101168). + +// CHECK-LABEL: fn f( fn f() -> usize { - // CHECK: switchInt(const true) -> [0: {{bb[0-9]+}}, otherwise: {{bb[0-9]+}}]; + // CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}]; 1 + if true { 1 } else { 2 } // CHECK: _0 = const 2_usize; } diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.rs b/tests/mir-opt/dataflow-const-prop/large_array_index.rs index 6b8a0248d19bc..fbca411e204d1 100644 --- a/tests/mir-opt/dataflow-const-prop/large_array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/large_array_index.rs @@ -4,7 +4,7 @@ // EMIT_MIR large_array_index.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { // check that we don't propagate this, because it's too large diff --git a/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs b/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs index c7e05579e4005..be8ce7310564c 100644 --- a/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs +++ b/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs @@ -1,7 +1,7 @@ // unit-test: DataflowConstProp // EMIT_MIR mult_by_zero.test.DataflowConstProp.diff -// CHECK-LABEL: fn test +// CHECK-LABEL: fn test( fn test(x : i32) -> i32 { x * 0 // CHECK: _0 = const 0_i32; diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.rs b/tests/mir-opt/dataflow-const-prop/offset_of.rs index a2032ea996edd..ff9fe7f2fbd25 100644 --- a/tests/mir-opt/dataflow-const-prop/offset_of.rs +++ b/tests/mir-opt/dataflow-const-prop/offset_of.rs @@ -29,45 +29,45 @@ struct Delta { // EMIT_MIR offset_of.concrete.DataflowConstProp.diff -// CHECK-LABEL: fn concrete +// CHECK-LABEL: fn concrete( fn concrete() { // CHECK: debug x => [[x:_.*]]; // CHECK: debug y => [[y:_.*]]; // CHECK: debug z0 => [[z0:_.*]]; // CHECK: debug z1 => [[z1:_.*]]; - // CHECK: [[x]] = must_use::(const 4_usize) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: [[x]] = must_use::(const 4_usize) -> {{.*}} let x = offset_of!(Alpha, x); - // CHECK: [[y]] = must_use::(const 0_usize) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: [[y]] = must_use::(const 0_usize) -> {{.*}} let y = offset_of!(Alpha, y); - // CHECK: [[z0]] = must_use::(const 2_usize) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: [[z0]] = must_use::(const 2_usize) -> {{.*}} let z0 = offset_of!(Alpha, z.0); - // CHECK: [[z1]] = must_use::(const 3_usize) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: [[z1]] = must_use::(const 3_usize) -> {{.*}} let z1 = offset_of!(Alpha, z.1); } // EMIT_MIR offset_of.generic.DataflowConstProp.diff -// CHECK-LABEL: generic +// CHECK-LABEL: fn generic( fn generic() { // CHECK: debug gx => [[gx:_.*]]; // CHECK: debug gy => [[gy:_.*]]; // CHECK: debug dx => [[dx:_.*]]; // CHECK: debug dy => [[dy:_.*]]; - // CHECK: [[gx]] = must_use::(move {{_[0-9]+}}) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: [[gx]] = must_use::(move {{_.*}}) -> {{.*}} let gx = offset_of!(Gamma, x); - // CHECK: [[gy]] = must_use::(move {{_[0-9]+}}) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: [[gy]] = must_use::(move {{_.*}}) -> {{.*}} let gy = offset_of!(Gamma, y); - // CHECK: [[dx]] = must_use::(const 0_usize) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: [[dx]] = must_use::(const 0_usize) -> {{.*}} let dx = offset_of!(Delta, x); - // CHECK: [[dy]] = must_use::(const 2_usize) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: [[dy]] = must_use::(const 2_usize) -> {{.*}} let dy = offset_of!(Delta, y); } diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs index fb66cda38ddbd..7bf2b18407854 100644 --- a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs +++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs @@ -8,21 +8,23 @@ fn escape(x: &T) {} fn some_function() {} // EMIT_MIR ref_without_sb.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { // CHECK: debug a => [[a:_.*]]; // CHECK: debug b => [[b:_.*]]; let mut a = 0; - // CHECK: {{_[0-9]+}} = escape::(move {{_[0-9]+}}) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: {{_.*}} = escape::(move {{_.*}}) -> {{.*}} escape(&a); a = 1; - // CHECK: {{_[0-9]+}} = some_function() -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: {{_.*}} = some_function() -> {{.*}} some_function(); // This should currently not be propagated. + // CHECK-NOT: [[b]] = const // CHECK: [[b]] = [[a]]; + // CHECK-NOT: [[b]] = const let b = a; } diff --git a/tests/mir-opt/dataflow-const-prop/repeat.rs b/tests/mir-opt/dataflow-const-prop/repeat.rs index 5d1c1a3edb695..80eb14dedea3a 100644 --- a/tests/mir-opt/dataflow-const-prop/repeat.rs +++ b/tests/mir-opt/dataflow-const-prop/repeat.rs @@ -3,15 +3,19 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR repeat.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { // CHECK: debug x => [[x:_.*]]; - // CHECK: {{_[0-9]+}} = const 8_usize; - // CHECK: {{_[0-9]+}} = const true; + // CHECK: [[array_lit:_.*]] = [const 42_u32; 8]; + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK: {{_.*}} = const 8_usize; + // CHECK: {{_.*}} = const true; // CHECK-LABEL: assert(const true - // CHECK: {{_[0-9]+}} = {{_[0-9]+}}[2 of 3]; - // CHECK: [[x]] = Add(move {{_[0-9]+}}, const 0_u32); + // CHECK-NOT: [[t:_.*]] = [[array_lit]][_ + // CHECK: [[t:_.*]] = [[array_lit]][2 of 3]; + // CHECK: [[x]] = Add(move [[t]], const 0_u32); let x: u32 = [42; 8][2] + 0; } diff --git a/tests/mir-opt/dataflow-const-prop/repr_transparent.rs b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs index d007301e568b1..39a2b357193ad 100644 --- a/tests/mir-opt/dataflow-const-prop/repr_transparent.rs +++ b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs @@ -7,7 +7,7 @@ struct I32(i32); // EMIT_MIR repr_transparent.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { // CHECK: debug x => [[x:_.*]]; // CHECK: debug y => [[y:_.*]]; diff --git a/tests/mir-opt/dataflow-const-prop/self_assign.rs b/tests/mir-opt/dataflow-const-prop/self_assign.rs index 7d58b972d655b..a5b232131286f 100644 --- a/tests/mir-opt/dataflow-const-prop/self_assign.rs +++ b/tests/mir-opt/dataflow-const-prop/self_assign.rs @@ -2,25 +2,25 @@ // EMIT_MIR self_assign.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { // CHECK: debug a => [[a:_.*]]; // CHECK: debug b => [[b:_.*]]; let mut a = 0; - // CHECK: [[a]] = Add(move {{_[0-9]+}}, const 1_i32); + // CHECK: [[a]] = Add(move {{_.*}}, const 1_i32); a = a + 1; - // CHECK: [[a]] = move {{_[0-9]+}}; + // CHECK: [[a]] = move {{_.*}}; a = a; // CHECK: [[b]] = &[[a]]; let mut b = &a; - // CHECK: [[b]] = move {{_[0-9]+}}; + // CHECK: [[b]] = move {{_.*}}; b = b; - // CHECK: [[a]] = move {{_[0-9]+}}; + // CHECK: [[a]] = move {{_.*}}; a = *b; } diff --git a/tests/mir-opt/dataflow-const-prop/self_assign_add.rs b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs index 09be3865d60b3..7bfbda7a96c61 100644 --- a/tests/mir-opt/dataflow-const-prop/self_assign_add.rs +++ b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs @@ -2,7 +2,7 @@ // EMIT_MIR self_assign_add.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { // CHECK: debug a => [[a:_.*]]; let mut a = 0; diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs index 6e39e39839410..9c610aabe821a 100644 --- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs @@ -10,9 +10,9 @@ // EMIT_MIR sibling_ptr.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { - // CHECK: debug x1 => [[x1:_[0-9]+]]; + // CHECK: debug x1 => [[x1:_.*]]; let mut x: (u8, u8) = (0, 0); unsafe { @@ -20,6 +20,6 @@ fn main() { *p.add(1) = 1; } - // CHECK: [[x1]] = ({{_[0-9]+}}.1: u8); + // CHECK: [[x1]] = ({{_.*}}.1: u8); let x1 = x.1; // should not be propagated } diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.rs b/tests/mir-opt/dataflow-const-prop/slice_len.rs index cd63980949638..65c87580330fc 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.rs +++ b/tests/mir-opt/dataflow-const-prop/slice_len.rs @@ -5,19 +5,30 @@ // EMIT_MIR slice_len.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { - // CHECK: debug local => [[local:_[0-9]+]]; - // CHECK: debug constant => [[constant:_[0-9]+]]; + // CHECK: debug local => [[local:_.*]]; + // CHECK: debug constant => [[constant:_.*]]; - // CHECK: {{_[0-9]+}} = const 3_usize; - // CHECK: {{_[0-9]+}} = const true; + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ + // CHECK: {{_.*}} = const 3_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true, - // CHECK: [[local]] = (*{{_[0-9]+}})[1 of 2]; + // CHECK: [[local]] = (*{{_.*}})[1 of 2]; let local = (&[1u32, 2, 3] as &[u32])[1]; + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ const SLICE: &[u32] = &[1, 2, 3]; + // CHECK: {{_.*}} = const 3_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true, - // CHECK: [[constant]] = (*{{_[0-9]+}})[1 of 2]; + // CHECK-NOT: [[constant]] = (*{{_.*}})[_ + // CHECK: [[constant]] = (*{{_.*}})[1 of 2]; let constant = SLICE[1]; } diff --git a/tests/mir-opt/dataflow-const-prop/struct.rs b/tests/mir-opt/dataflow-const-prop/struct.rs index 4eec15a7f1630..a7e0f6a987d5a 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.rs +++ b/tests/mir-opt/dataflow-const-prop/struct.rs @@ -12,25 +12,25 @@ struct BigStruct(f32, Option, &'static [f32]); // EMIT_MIR struct.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { - // CHECK: debug s => [[s:_[0-9]+]]; - // CHECK: debug a => [[a:_[0-9]+]]; - // CHECK: debug b => [[b:_[0-9]+]]; - // CHECK: debug a1 => [[a1:_[0-9]+]]; - // CHECK: debug b1 => [[b1:_[0-9]+]]; - // CHECK: debug c1 => [[c1:_[0-9]+]]; - // CHECK: debug a2 => [[a2:_[0-9]+]]; - // CHECK: debug b2 => [[b2:_[0-9]+]]; - // CHECK: debug c2 => [[c2:_[0-9]+]]; - // CHECK: debug ss => [[ss:_[0-9]+]]; - // CHECK: debug a3 => [[a3:_[0-9]+]]; - // CHECK: debug b3 => [[b3:_[0-9]+]]; - // CHECK: debug c3 => [[c3:_[0-9]+]]; - // CHECK: debug a4 => [[a4:_[0-9]+]]; - // CHECK: debug b4 => [[b4:_[0-9]+]]; - // CHECK: debug c4 => [[c4:_[0-9]+]]; - // CHECK: debug bs => [[bs:_[0-9]+]]; + // CHECK: debug s => [[s:_.*]]; + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK: debug a1 => [[a1:_.*]]; + // CHECK: debug b1 => [[b1:_.*]]; + // CHECK: debug c1 => [[c1:_.*]]; + // CHECK: debug a2 => [[a2:_.*]]; + // CHECK: debug b2 => [[b2:_.*]]; + // CHECK: debug c2 => [[c2:_.*]]; + // CHECK: debug ss => [[ss:_.*]]; + // CHECK: debug a3 => [[a3:_.*]]; + // CHECK: debug b3 => [[b3:_.*]]; + // CHECK: debug c3 => [[c3:_.*]]; + // CHECK: debug a4 => [[a4:_.*]]; + // CHECK: debug b4 => [[b4:_.*]]; + // CHECK: debug c4 => [[c4:_.*]]; + // CHECK: debug bs => [[bs:_.*]]; // CHECK: [[s]] = const S(1_i32); let mut s = S(1); @@ -46,34 +46,34 @@ fn main() { // CHECK: [[a1]] = const 4f32; // CHECK: [[b1]] = const Option::::Some(S(1_i32)); - // CHECK: [[c1]] = ({{_[0-9]+}}.2: &[f32]); + // CHECK: [[c1]] = ({{_.*}}.2: &[f32]); let SmallStruct(a1, b1, c1) = SMALL_VAL; static SMALL_STAT: &SmallStruct = &SmallStruct(9., None, &[13.]); // CHECK: [[a2]] = const 9f32; - // CHECK: [[b2]] = ((*{{_[0-9]+}}).1: std::option::Option); - // CHECK: [[c2]] = ((*{{_[0-9]+}}).2: &[f32]); + // CHECK: [[b2]] = ((*{{_.*}}).1: std::option::Option); + // CHECK: [[c2]] = ((*{{_.*}}).2: &[f32]); let SmallStruct(a2, b2, c2) = *SMALL_STAT; - // CHECK: [[ss]] = SmallStruct(const 9f32, move {{_[0-9]+}}, move {{_[0-9]+}}); + // CHECK: [[ss]] = SmallStruct(const 9f32, move {{_.*}}, move {{_.*}}); let ss = SmallStruct(a2, b2, c2); const BIG_VAL: BigStruct = BigStruct(25., None, &[]); // CHECK: [[a3]] = const 25f32; - // CHECK: [[b3]] = ({{_[0-9]+}}.1: std::option::Option); - // CHECK: [[c3]] = ({{_[0-9]+}}.2: &[f32]); + // CHECK: [[b3]] = ({{_.*}}.1: std::option::Option); + // CHECK: [[c3]] = ({{_.*}}.2: &[f32]); let BigStruct(a3, b3, c3) = BIG_VAL; static BIG_STAT: &BigStruct = &BigStruct(82., Some(S(35)), &[45., 72.]); // CHECK: [[a4]] = const 82f32; // CHECK: [[b4]] = const Option::::Some(S(35_i32)); - // CHECK: [[c4]] = ((*{{_[0-9]+}}).2: &[f32]); + // CHECK: [[c4]] = ((*{{_.*}}).2: &[f32]); let BigStruct(a4, b4, c4) = *BIG_STAT; // We arbitrarily limit the size of synthetized values to 4 pointers. // `BigStruct` can be read, but we will keep a MIR aggregate for this. - // CHECK: [[bs]] = BigStruct(const 82f32, const Option::::Some(S(35_i32)), move {{_[0-9]+}}); + // CHECK: [[bs]] = BigStruct(const 82f32, const Option::::Some(S(35_i32)), move {{_.*}}); let bs = BigStruct(a4, b4, c4); } diff --git a/tests/mir-opt/dataflow-const-prop/terminator.rs b/tests/mir-opt/dataflow-const-prop/terminator.rs index 985eddad26440..37bf3b3347024 100644 --- a/tests/mir-opt/dataflow-const-prop/terminator.rs +++ b/tests/mir-opt/dataflow-const-prop/terminator.rs @@ -5,10 +5,10 @@ fn foo(n: i32) {} // EMIT_MIR terminator.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { let a = 1; // Checks that we propagate into terminators. - // CHECK: {{_[0-9]+}} = foo(const 2_i32) -> [return: {{bb[0-9]+}}, unwind continue]; + // CHECK: {{_.*}} = foo(const 2_i32) -> [return: {{bb.*}}, unwind continue]; foo(a + 1); } diff --git a/tests/mir-opt/dataflow-const-prop/tuple.rs b/tests/mir-opt/dataflow-const-prop/tuple.rs index bd5adeda8b3dc..563558da04a5d 100644 --- a/tests/mir-opt/dataflow-const-prop/tuple.rs +++ b/tests/mir-opt/dataflow-const-prop/tuple.rs @@ -3,12 +3,12 @@ // EMIT_MIR tuple.main.DataflowConstProp.diff -// CHECK-LABEL: fn main +// CHECK-LABEL: fn main( fn main() { - // CHECK: debug a => [[a:_[0-9]+]]; - // CHECK: debug b => [[b:_[0-9]+]]; - // CHECK: debug c => [[c:_[0-9]+]]; - // CHECK: debug d => [[d:_[0-9]+]]; + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK: debug c => [[c:_.*]]; + // CHECK: debug d => [[d:_.*]]; // CHECK: [[a]] = const (1_i32, 2_i32); let mut a = (1, 2); From 1c886d794c1772eb6a51e84939ef1093e9e10e17 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Thu, 11 Jan 2024 23:22:33 -0800 Subject: [PATCH 13/35] resolve code reviews --- tests/mir-opt/dataflow-const-prop/array_index.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/array_index.rs b/tests/mir-opt/dataflow-const-prop/array_index.rs index 4b070e1d6d6f6..e21388ff5d211 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/array_index.rs @@ -9,8 +9,13 @@ fn main() { // CHECK: let mut [[array_lit:_.*]]: [u32; 4]; // CHECK: debug x => [[x:_.*]]; - let x: u32 = [0, 1, 2, 3][2]; // CHECK: [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; - // CHECK-LABEL: assert(const true, - // CHECK: [[x]] = [[array_lit]][2 of 3]; + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ + // CHECK: {{_.*}} = const 4_usize; + // CHECK: {{_.*}} = const true; + // CHECK-LABEL: assert(const true + // CHECK: [[x]] = [[array_lit]][2 of 3]; + let x: u32 = [0, 1, 2, 3][2]; } From cd77d59f97cba2909b457b2ebb36f201b9dcb532 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Fri, 12 Jan 2024 20:50:28 -0800 Subject: [PATCH 14/35] update enum.rs for code review --- tests/mir-opt/dataflow-const-prop/enum.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index 26fdda2664a95..8a6fe3a3fdaa1 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -118,6 +118,7 @@ fn multiple(x: bool, i: u8) { // CHECK: debug x => [[x:_.*]]; // CHECK: debug e => [[e:_.*]]; // CHECK: debug x2 => [[x2:_.*]]; + // CHECK: debug y => [[y:_.*]]; let e = if x { // CHECK: [[e]] = Option::::Some(move {{_.*}}); Some(i) @@ -128,10 +129,18 @@ fn multiple(x: bool, i: u8) { // The dataflow state must have: // discriminant(e) => Top // (e as Some).0 => Top + // CHECK-NOT: [[x2]] = const 5 // CHECK: [[x2]] = const 0_u8; - // CHECK: [[x2]] = {{_.*}}; + // CHECK-NOT: [[x2]] = const 5 + // CHECK: [[some:_.*]] = (({{_.*}} as Some + // CHECK: [[x2]] = [[some]]; let x2 = match e { Some(i) => i, None => 0 }; + // Therefore, `x2` should be `Top` here, and no replacement shall happen. + + // CHECK-NOT: [[y]] = const + // CHECK: [[y]] = [[x2]]; + // CHECK-NOT: [[y]] = const let y = x2; } From 5747eceef859c6e1ac74c04723ac9e2b5e039e1f Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Sun, 14 Jan 2024 22:35:00 -0800 Subject: [PATCH 15/35] add FIXME for default_boxed_slice.rs --- tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs index b15809f2510ff..bfa52b694d0ec 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs @@ -4,6 +4,8 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR_FOR_EACH_PANIC_STRATEGY +// This test is to check ICE in issue [#115789](https://github.com/rust-lang/rust/issues/115789). + struct A { foo: Box<[bool]>, } @@ -14,13 +16,14 @@ struct A { // CHECK-LABEL: fn main( fn main() { // ConstProp will create a constant of type `Box<[bool]>`. + // FIXME: it is not yet a constant. + // Verify that `DataflowConstProp` does not ICE trying to dereference it directly. // CHECK: debug a => [[a:_.*]]; // We may check other inlined functions as well... - // CHECK: [[box_obj:_.*]] = Box::<[bool]>(_3, const std::alloc::Global); - // CHECK: [[a]] = A { foo: move [[box_obj]] }; - // FIXME: we do not have `const Box::<[bool]>` after constprop right now. + // CHECK-LABEL: _.* = Box::<[bool]>( + // FIXME: should be `_.* = const Box::<[bool]>` let a: A = A { foo: Box::default() }; } From edba94907d2f84f35f8e5673a363bf2d42e1c29a Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Sat, 20 Jan 2024 08:09:14 -0800 Subject: [PATCH 16/35] update misuse of check-label --- tests/mir-opt/dataflow-const-prop/array_index.rs | 2 +- tests/mir-opt/dataflow-const-prop/checked.rs | 4 ++-- tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs | 4 ++-- tests/mir-opt/dataflow-const-prop/inherit_overflow.rs | 2 +- tests/mir-opt/dataflow-const-prop/large_array_index.rs | 2 +- tests/mir-opt/dataflow-const-prop/repeat.rs | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/array_index.rs b/tests/mir-opt/dataflow-const-prop/array_index.rs index e21388ff5d211..8f0cc489a5bb7 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/array_index.rs @@ -15,7 +15,7 @@ fn main() { // CHECK-NOT: assert(move _ // CHECK: {{_.*}} = const 4_usize; // CHECK: {{_.*}} = const true; - // CHECK-LABEL: assert(const true + // CHECK: assert(const true // CHECK: [[x]] = [[array_lit]][2 of 3]; let x: u32 = [0, 1, 2, 3][2]; } diff --git a/tests/mir-opt/dataflow-const-prop/checked.rs b/tests/mir-opt/dataflow-const-prop/checked.rs index 45331f91323e4..30b0afa8334dd 100644 --- a/tests/mir-opt/dataflow-const-prop/checked.rs +++ b/tests/mir-opt/dataflow-const-prop/checked.rs @@ -19,14 +19,14 @@ fn main() { // CHECK: [[b]] = const 2_i32; let b = 2; - // CHECK-LABEL: assert(!const false, + // CHECK: assert(!const false, // CHECK: [[c]] = const 3_i32; let c = a + b; // CHECK: [[d]] = const _; let d = i32::MAX; - // CHECK-LABEL: assert(!const true, + // CHECK: assert(!const true, // CHECK: [[e]] = const i32::MIN; let e = d + 1; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs index bfa52b694d0ec..fb708e5084bb9 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs @@ -23,7 +23,7 @@ fn main() { // CHECK: debug a => [[a:_.*]]; // We may check other inlined functions as well... - // CHECK-LABEL: _.* = Box::<[bool]>( - // FIXME: should be `_.* = const Box::<[bool]>` + // CHECK: {{_.*}} = Box::<[bool]>( + // FIXME: should be `{{_.*}} = const Box::<[bool]>` let a: A = A { foo: Box::default() }; } diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs index 0a2774c782009..b0acc31e0dbcc 100644 --- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs @@ -9,6 +9,6 @@ fn main() { // Propagating the overflow is ok as codegen will just skip emitting the panic. // CHECK: {{_.*}} = const (0_u8, true); - // CHECK-LABEL: assert(!const true, + // CHECK: assert(!const true, let _ = ::add(255, 1); } diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.rs b/tests/mir-opt/dataflow-const-prop/large_array_index.rs index fbca411e204d1..62be2c3824fa5 100644 --- a/tests/mir-opt/dataflow-const-prop/large_array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/large_array_index.rs @@ -12,7 +12,7 @@ fn main() { // CHECK: [[array_lit:_.*]] = [const 0_u8; 5000]; // CHECK: {{_.*}} = const 5000_usize; // CHECK: {{_.*}} = const true; - // CHECK-LABEL: assert(const true + // CHECK: assert(const true // CHECK: [[x]] = [[array_lit]][2 of 3]; let x: u8 = [0_u8; 5000][2]; } diff --git a/tests/mir-opt/dataflow-const-prop/repeat.rs b/tests/mir-opt/dataflow-const-prop/repeat.rs index 80eb14dedea3a..daa8dbaf07655 100644 --- a/tests/mir-opt/dataflow-const-prop/repeat.rs +++ b/tests/mir-opt/dataflow-const-prop/repeat.rs @@ -12,7 +12,7 @@ fn main() { // CHECK-NOT: {{_.*}} = Lt( // CHECK: {{_.*}} = const 8_usize; // CHECK: {{_.*}} = const true; - // CHECK-LABEL: assert(const true + // CHECK: assert(const true // CHECK-NOT: [[t:_.*]] = [[array_lit]][_ // CHECK: [[t:_.*]] = [[array_lit]][2 of 3]; From 7ad307dc9d014fb8d06e42d495c88328455510c1 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Sat, 20 Jan 2024 08:22:07 -0800 Subject: [PATCH 17/35] finish a pattern in `enum.rs` --- tests/mir-opt/dataflow-const-prop/enum.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index 8a6fe3a3fdaa1..86288020bab45 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -132,7 +132,7 @@ fn multiple(x: bool, i: u8) { // CHECK-NOT: [[x2]] = const 5 // CHECK: [[x2]] = const 0_u8; // CHECK-NOT: [[x2]] = const 5 - // CHECK: [[some:_.*]] = (({{_.*}} as Some + // CHECK: [[some:_.*]] = (({{_.*}} as Some).0: u8) // CHECK: [[x2]] = [[some]]; let x2 = match e { Some(i) => i, None => 0 }; From 65b10839d6cc033d65831666565ffda5077793f8 Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Mon, 22 Jan 2024 17:34:49 -0800 Subject: [PATCH 18/35] update enum.rs --- tests/mir-opt/dataflow-const-prop/enum.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index 86288020bab45..7ad64d05be434 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -129,9 +129,7 @@ fn multiple(x: bool, i: u8) { // The dataflow state must have: // discriminant(e) => Top // (e as Some).0 => Top - // CHECK-NOT: [[x2]] = const 5 // CHECK: [[x2]] = const 0_u8; - // CHECK-NOT: [[x2]] = const 5 // CHECK: [[some:_.*]] = (({{_.*}} as Some).0: u8) // CHECK: [[x2]] = [[some]]; let x2 = match e { Some(i) => i, None => 0 }; From 699b59c01d1b3e67b5a29646705d9824e03ff1ad Mon Sep 17 00:00:00 2001 From: sfzhu93 Date: Sun, 28 Jan 2024 22:44:32 -0800 Subject: [PATCH 19/35] update terminator.rs --- tests/mir-opt/dataflow-const-prop/terminator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mir-opt/dataflow-const-prop/terminator.rs b/tests/mir-opt/dataflow-const-prop/terminator.rs index 37bf3b3347024..4472861f132db 100644 --- a/tests/mir-opt/dataflow-const-prop/terminator.rs +++ b/tests/mir-opt/dataflow-const-prop/terminator.rs @@ -9,6 +9,6 @@ fn foo(n: i32) {} fn main() { let a = 1; // Checks that we propagate into terminators. - // CHECK: {{_.*}} = foo(const 2_i32) -> [return: {{bb.*}}, unwind continue]; + // CHECK: {{_.*}} = foo(const 2_i32) -> [return: {{bb.*}}, unwind foo(a + 1); } From 44d8ecbfb85d1649a4267e33c847f79a125b99f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 29 Jan 2024 19:07:36 +0000 Subject: [PATCH 20/35] Only suggest removal of `as_*` and `to_` conversion methods on E0308 Instead of ``` error[E0308]: mismatched types --> tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.rs:9:5 | 4 | fn get_name() -> String { | ------ expected `String` because of return type ... 9 | your_name.trim() //~ ERROR E0308 | ^^^^^^^^^^^^^^^^ expected `String`, found `&str` | help: try removing the method call | 9 - your_name.trim() 9 + your_name ``` output ``` error[E0308]: mismatched types --> $DIR/only-suggest-removal-of-conversion-method-calls.rs:9:5 | LL | fn get_name() -> String { | ------ expected `String` because of return type ... LL | your_name.trim() | ^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` | | | expected `String`, found `&str` ``` Fix #114329. --- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 ++ ...gest-removal-of-conversion-method-calls.fixed | 16 ++++++++++++++++ ...suggest-removal-of-conversion-method-calls.rs | 16 ++++++++++++++++ ...est-removal-of-conversion-method-calls.stderr | 14 ++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.fixed create mode 100644 tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.rs create mode 100644 tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 95c1139e43e44..5395ffda1d134 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -261,6 +261,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr.kind && let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr) && self.can_coerce(recv_ty, expected) + && let name = method.name.as_str() + && (name.starts_with("to_") || name.starts_with("as_") || name == "into") { let span = if let Some(recv_span) = recv_expr.span.find_ancestor_inside(expr.span) { expr.span.with_lo(recv_span.hi()) diff --git a/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.fixed b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.fixed new file mode 100644 index 0000000000000..570d91d949bfc --- /dev/null +++ b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.fixed @@ -0,0 +1,16 @@ +// run-rustfix +use std::io::stdin; + +fn get_name() -> String { + let mut your_name = String::new(); + stdin() + .read_line(&mut your_name) + .expect("Failed to read the line for some reason"); + your_name.trim().to_string() //~ ERROR E0308 +} + +fn main() { + println!("Hello, What is your name? "); + let your_name = get_name(); + println!("Hello, {}", your_name) +} diff --git a/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.rs b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.rs new file mode 100644 index 0000000000000..93e8c0af0323e --- /dev/null +++ b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.rs @@ -0,0 +1,16 @@ +// run-rustfix +use std::io::stdin; + +fn get_name() -> String { + let mut your_name = String::new(); + stdin() + .read_line(&mut your_name) + .expect("Failed to read the line for some reason"); + your_name.trim() //~ ERROR E0308 +} + +fn main() { + println!("Hello, What is your name? "); + let your_name = get_name(); + println!("Hello, {}", your_name) +} diff --git a/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr new file mode 100644 index 0000000000000..c721ceb11463f --- /dev/null +++ b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/only-suggest-removal-of-conversion-method-calls.rs:9:5 + | +LL | fn get_name() -> String { + | ------ expected `String` because of return type +... +LL | your_name.trim() + | ^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` + | | + | expected `String`, found `&str` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From f9e2a6bd058f13f47a1ce3de638538272173b29d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 31 Jan 2024 09:25:42 +1100 Subject: [PATCH 21/35] Make `Diagnostic::is_error` return false for `Level::FailureNote`. It doesn't affect behaviour, but makes sense with (a) `FailureNote` having `()` as its emission guarantee, and (b) in `Level` the `is_error` levels now are all listed before the non-`is_error` levels. --- compiler/rustc_errors/src/diagnostic.rs | 4 ++-- compiler/rustc_errors/src/lib.rs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index bf1ab37a1cf48..c728cc6631ad5 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -238,8 +238,7 @@ impl Diagnostic { Level::Bug | Level::DelayedBug(DelayedBugKind::Normal) | Level::Fatal - | Level::Error - | Level::FailureNote => true, + | Level::Error => true, Level::ForceWarning(_) | Level::Warning @@ -248,6 +247,7 @@ impl Diagnostic { | Level::OnceNote | Level::Help | Level::OnceHelp + | Level::FailureNote | Level::Allow | Level::Expect(_) => false, } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 960b68196ff02..c0c2152587f83 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1545,6 +1545,8 @@ pub enum Level { /// /// The [`LintExpectationId`] is used for expected lint diagnostics. In all other cases this /// should be `None`. + /// + /// Its `EmissionGuarantee` is `()`. ForceWarning(Option), /// A warning about the code being compiled. Does not prevent compilation from finishing. @@ -1574,7 +1576,8 @@ pub enum Level { /// Its `EmissionGuarantee` is `()`. OnceHelp, - /// Similar to `Note`, but used in cases where compilation has failed. Rare. + /// Similar to `Note`, but used in cases where compilation has failed. When printed for human + /// consumption, it doesn't have any kind of `note:` label. Rare. /// /// Its `EmissionGuarantee` is `()`. FailureNote, From 8b25343c6f26b29aeab7a6b6625f85fab6c39639 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 31 Jan 2024 13:56:22 +1100 Subject: [PATCH 22/35] Tighten the assertion in `downgrade_to_delayed_bug`. I.e. `Bug` and `Fatal` level diagnostics are never downgraded. --- compiler/rustc_errors/src/diagnostic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index c728cc6631ad5..d888c4540b9fa 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -306,7 +306,7 @@ impl Diagnostic { #[track_caller] pub fn downgrade_to_delayed_bug(&mut self) { assert!( - self.is_error(), + matches!(self.level, Level::Error | Level::DelayedBug(_)), "downgrade_to_delayed_bug: cannot downgrade {:?} to DelayedBug: not an error", self.level ); From 6a48407eff38e2b331ded0620bb7d4b8a59f9102 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 31 Jan 2024 14:48:48 +1100 Subject: [PATCH 23/35] Remove unnecessary setting of `suppressed_expected_diag`. It's currently set in three places. Two of them seem to be unnecessary, and the one in `emit_diagnostic` can be changed to only trigger for `Expect` level diagnostics. After this change the name `suppressed_expected_diag` actually matches the code's behaviour, which is nice. --- compiler/rustc_errors/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index c0c2152587f83..e09ca9c6c7947 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1179,7 +1179,6 @@ impl DiagCtxt { inner.check_unstable_expect_diagnostics = true; if !diags.is_empty() { - inner.suppressed_expected_diag = true; for mut diag in diags.into_iter() { diag.update_unstable_expectation_id(unstable_to_stable); @@ -1291,15 +1290,10 @@ impl DiagCtxtInner { } if diagnostic.has_future_breakage() { - // Future breakages aren't emitted if they're Level::Allow, - // but they still need to be constructed and stashed below, - // so they'll trigger the good-path bug check. - self.suppressed_expected_diag = true; self.future_breakage_diagnostics.push(diagnostic.clone()); } if let Some(expectation_id) = diagnostic.level.get_expectation_id() { - self.suppressed_expected_diag = true; self.fulfilled_expectations.insert(expectation_id.normalize()); } @@ -1310,7 +1304,13 @@ impl DiagCtxtInner { return None; } - if matches!(diagnostic.level, Expect(_) | Allow) { + if matches!(diagnostic.level, Expect(_)) { + self.suppressed_expected_diag = true; + (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); + return None; + } + + if matches!(diagnostic.level, Allow) { (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); return None; } From b38c36b34d7f55169f9065d2784a7345673b0bde Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 31 Jan 2024 15:10:23 +1100 Subject: [PATCH 24/35] Refactor `emit_diagnostic`. - Combine two different blocks involving `diagnostic.level.get_expectation_id()` into one. - Combine several `if`s involving `diagnostic.level` into a single `match`. This requires reordering some of the operations, but this has no functional effect. --- compiler/rustc_errors/src/lib.rs | 83 +++++++++++++++----------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index e09ca9c6c7947..357688354fbd9 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1248,24 +1248,36 @@ impl DiagCtxtInner { } fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option { - // The `LintExpectationId` can be stable or unstable depending on when it was created. - // Diagnostics created before the definition of `HirId`s are unstable and can not yet - // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by - // a stable one by the `LintLevelsBuilder`. - if let Some(LintExpectationId::Unstable { .. }) = diagnostic.level.get_expectation_id() { - self.unstable_expect_diagnostics.push(diagnostic.clone()); - return None; + if let Some(expectation_id) = diagnostic.level.get_expectation_id() { + // The `LintExpectationId` can be stable or unstable depending on when it was created. + // Diagnostics created before the definition of `HirId`s are unstable and can not yet + // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by + // a stable one by the `LintLevelsBuilder`. + if let LintExpectationId::Unstable { .. } = expectation_id { + self.unstable_expect_diagnostics.push(diagnostic.clone()); + return None; + } + self.fulfilled_expectations.insert(expectation_id.normalize()); + } + + if diagnostic.has_future_breakage() { + self.future_breakage_diagnostics.push(diagnostic.clone()); + } + + if matches!(diagnostic.level, DelayedBug(_)) && self.flags.eagerly_emit_delayed_bugs { + diagnostic.level = Error; } - // FIXME(eddyb) this should check for `has_errors` and stop pushing - // once *any* errors were emitted (and truncate `span_delayed_bugs` - // when an error is first emitted, also), but maybe there's a case - // in which that's not sound? otherwise this is really inefficient. match diagnostic.level { - DelayedBug(_) if self.flags.eagerly_emit_delayed_bugs => { - diagnostic.level = Error; + // This must come after the possible promotion of `DelayedBug` to `Error` above. + Fatal | Error if self.treat_next_err_as_bug() => { + diagnostic.level = Bug; } DelayedBug(DelayedBugKind::Normal) => { + // FIXME(eddyb) this should check for `has_errors` and stop pushing + // once *any* errors were emitted (and truncate `span_delayed_bugs` + // when an error is first emitted, also), but maybe there's a case + // in which that's not sound? otherwise this is really inefficient. let backtrace = std::backtrace::Backtrace::capture(); self.span_delayed_bugs .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace)); @@ -1280,39 +1292,22 @@ impl DiagCtxtInner { return None; } - _ => {} - } - - // This must come after the possible promotion of `DelayedBug` to - // `Error` above. - if matches!(diagnostic.level, Error | Fatal) && self.treat_next_err_as_bug() { - diagnostic.level = Bug; - } - - if diagnostic.has_future_breakage() { - self.future_breakage_diagnostics.push(diagnostic.clone()); - } - - if let Some(expectation_id) = diagnostic.level.get_expectation_id() { - self.fulfilled_expectations.insert(expectation_id.normalize()); - } - - if diagnostic.level == Warning && !self.flags.can_emit_warnings { - if diagnostic.has_future_breakage() { + Warning if !self.flags.can_emit_warnings => { + if diagnostic.has_future_breakage() { + (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); + } + return None; + } + Allow => { (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); + return None; } - return None; - } - - if matches!(diagnostic.level, Expect(_)) { - self.suppressed_expected_diag = true; - (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); - return None; - } - - if matches!(diagnostic.level, Allow) { - (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); - return None; + Expect(_) => { + self.suppressed_expected_diag = true; + (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); + return None; + } + _ => {} } let mut guaranteed = None; From 23510b202bfeecb56f6e1a1e4266ee4056d7d2e9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 31 Jan 2024 11:23:54 +1100 Subject: [PATCH 25/35] Split `Level::DelayedBug` in two. The two kinds of delayed bug have quite different semantics so a stronger conceptual separation is nice. (`is_error` is a good example, because the two kinds have different behaviour.) The commit also moves the `DelayedBug` variant after `Error` in `Level`, to reflect the fact that it's weaker than `Error` -- it might trigger an error but also might not. (The pre-existing `downgrade_to_delayed_bug` function also reflects the notion that delayed bugs are lower/after normal errors.) Plus it condenses some of the comments on `Level` into a table, for easier reading, and introduces `can_be_top_or_sub` to indicate which levels can be used in top-level diagnostics vs. subdiagnostics. Finally, it renames `DiagCtxtInner::span_delayed_bugs` as `DiagCtxtInner::delayed_bugs`. The `span_` prefix is unnecessary because some delayed bugs don't have a span. --- compiler/rustc_error_messages/src/lib.rs | 2 +- .../src/annotate_snippet_emitter_writer.rs | 6 +- compiler/rustc_errors/src/diagnostic.rs | 18 +- compiler/rustc_errors/src/emitter.rs | 1 + compiler/rustc_errors/src/lib.rs | 160 ++++++++++-------- .../equality-in-canonical-query.clone.stderr | 2 +- ...equality_in_canonical_query.current.stderr | 2 +- 7 files changed, 101 insertions(+), 90 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 8fd7c5764797e..d212e18b4cd72 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -378,7 +378,7 @@ impl From> for DiagnosticMessage { } } -/// A workaround for "good path" ICEs when formatting types in disabled lints. +/// A workaround for good_path_delayed_bug ICEs when formatting types in disabled lints. /// /// Delays formatting until `.into(): DiagnosticMessage` is used. pub struct DelayDm(pub F); diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 949f52ef6b586..06f6c58c5ff2e 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -85,7 +85,11 @@ fn source_string(file: Lrc, line: &Line) -> String { /// Maps `Diagnostic::Level` to `snippet::AnnotationType` fn annotation_type_for_level(level: Level) -> AnnotationType { match level { - Level::Bug | Level::DelayedBug(_) | Level::Fatal | Level::Error => AnnotationType::Error, + Level::Bug + | Level::Fatal + | Level::Error + | Level::DelayedBug + | Level::GoodPathDelayedBug => AnnotationType::Error, Level::ForceWarning(_) | Level::Warning => AnnotationType::Warning, Level::Note | Level::OnceNote => AnnotationType::Note, Level::Help | Level::OnceHelp => AnnotationType::Help, diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index d888c4540b9fa..10964eb7915d8 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1,8 +1,7 @@ use crate::snippet::Style; use crate::{ - CodeSuggestion, DelayedBugKind, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, - ErrCode, Level, MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart, - SuggestionStyle, + CodeSuggestion, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, ErrCode, Level, + MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle, }; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_error_messages::fluent_value_from_str_list_sep_by_and; @@ -235,14 +234,11 @@ impl Diagnostic { pub fn is_error(&self) -> bool { match self.level { - Level::Bug - | Level::DelayedBug(DelayedBugKind::Normal) - | Level::Fatal - | Level::Error => true, + Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => true, - Level::ForceWarning(_) + Level::GoodPathDelayedBug + | Level::ForceWarning(_) | Level::Warning - | Level::DelayedBug(DelayedBugKind::GoodPath) | Level::Note | Level::OnceNote | Level::Help @@ -306,11 +302,11 @@ impl Diagnostic { #[track_caller] pub fn downgrade_to_delayed_bug(&mut self) { assert!( - matches!(self.level, Level::Error | Level::DelayedBug(_)), + matches!(self.level, Level::Error | Level::DelayedBug), "downgrade_to_delayed_bug: cannot downgrade {:?} to DelayedBug: not an error", self.level ); - self.level = Level::DelayedBug(DelayedBugKind::Normal); + self.level = Level::DelayedBug; } /// Appends a labeled span to the diagnostic. diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 9f76c1dd248b0..760e66fd34ad5 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2118,6 +2118,7 @@ impl HumanEmitter { } if !self.short_message { for child in children { + assert!(child.level.can_be_top_or_sub().1); let span = &child.span; if let Err(err) = self.emit_messages_default_inner( span, diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 357688354fbd9..49476daffcd0c 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -440,7 +440,7 @@ struct DiagCtxtInner { has_printed: bool, emitter: Box, - span_delayed_bugs: Vec, + delayed_bugs: Vec, good_path_delayed_bugs: Vec, /// This flag indicates that an expected diagnostic was emitted and suppressed. /// This is used for the `good_path_delayed_bugs` check. @@ -524,8 +524,7 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) { pub static TRACK_DIAGNOSTIC: AtomicRef = AtomicRef::new(&(default_track_diagnostic as _)); -#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)] -pub enum DelayedBugKind { +enum DelayedBugKind { Normal, GoodPath, } @@ -558,11 +557,6 @@ impl Drop for DiagCtxtInner { self.flush_delayed(DelayedBugKind::Normal) } - // FIXME(eddyb) this explains what `good_path_delayed_bugs` are! - // They're `span_delayed_bugs` but for "require some diagnostic happened" - // instead of "require some error happened". Sadly that isn't ideal, as - // lints can be `#[allow]`'d, potentially leading to this triggering. - // Also, "good path" should be replaced with a better naming. if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() { self.flush_delayed(DelayedBugKind::GoodPath); } @@ -609,7 +603,7 @@ impl DiagCtxt { deduplicated_warn_count: 0, has_printed: false, emitter, - span_delayed_bugs: Vec::new(), + delayed_bugs: Vec::new(), good_path_delayed_bugs: Vec::new(), suppressed_expected_diag: false, taught_diagnostics: Default::default(), @@ -665,7 +659,7 @@ impl DiagCtxt { inner.has_printed = false; // actually free the underlying memory (which `clear` would not do) - inner.span_delayed_bugs = Default::default(); + inner.delayed_bugs = Default::default(); inner.good_path_delayed_bugs = Default::default(); inner.taught_diagnostics = Default::default(); inner.emitted_diagnostic_codes = Default::default(); @@ -866,8 +860,7 @@ impl DiagCtxt { /// directly). #[track_caller] pub fn delayed_bug(&self, msg: impl Into) -> ErrorGuaranteed { - DiagnosticBuilder::::new(self, DelayedBug(DelayedBugKind::Normal), msg) - .emit() + DiagnosticBuilder::::new(self, DelayedBug, msg).emit() } /// Like `delayed_bug`, but takes an additional span. @@ -880,15 +873,12 @@ impl DiagCtxt { sp: impl Into, msg: impl Into, ) -> ErrorGuaranteed { - DiagnosticBuilder::::new(self, DelayedBug(DelayedBugKind::Normal), msg) - .with_span(sp) - .emit() + DiagnosticBuilder::::new(self, DelayedBug, msg).with_span(sp).emit() } - // FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's - // where the explanation of what "good path" is (also, it should be renamed). + /// Ensures that a diagnostic is printed. See `Level::GoodPathDelayedBug`. pub fn good_path_delayed_bug(&self, msg: impl Into) { - DiagnosticBuilder::<()>::new(self, DelayedBug(DelayedBugKind::GoodPath), msg).emit() + DiagnosticBuilder::<()>::new(self, GoodPathDelayedBug, msg).emit() } #[track_caller] @@ -962,7 +952,7 @@ impl DiagCtxt { pub fn has_errors_or_lint_errors_or_delayed_bugs(&self) -> Option { let inner = self.inner.borrow(); let result = - inner.has_errors() || inner.lint_err_count > 0 || !inner.span_delayed_bugs.is_empty(); + inner.has_errors() || inner.lint_err_count > 0 || !inner.delayed_bugs.is_empty(); result.then(|| { #[allow(deprecated)] ErrorGuaranteed::unchecked_claim_error_was_emitted() @@ -1248,6 +1238,8 @@ impl DiagCtxtInner { } fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option { + assert!(diagnostic.level.can_be_top_or_sub().0); + if let Some(expectation_id) = diagnostic.level.get_expectation_id() { // The `LintExpectationId` can be stable or unstable depending on when it was created. // Diagnostics created before the definition of `HirId`s are unstable and can not yet @@ -1264,32 +1256,33 @@ impl DiagCtxtInner { self.future_breakage_diagnostics.push(diagnostic.clone()); } - if matches!(diagnostic.level, DelayedBug(_)) && self.flags.eagerly_emit_delayed_bugs { + if matches!(diagnostic.level, DelayedBug | GoodPathDelayedBug) + && self.flags.eagerly_emit_delayed_bugs + { diagnostic.level = Error; } match diagnostic.level { - // This must come after the possible promotion of `DelayedBug` to `Error` above. + // This must come after the possible promotion of `DelayedBug`/`GoodPathDelayedBug` to + // `Error` above. Fatal | Error if self.treat_next_err_as_bug() => { diagnostic.level = Bug; } - DelayedBug(DelayedBugKind::Normal) => { + DelayedBug => { // FIXME(eddyb) this should check for `has_errors` and stop pushing - // once *any* errors were emitted (and truncate `span_delayed_bugs` + // once *any* errors were emitted (and truncate `delayed_bugs` // when an error is first emitted, also), but maybe there's a case // in which that's not sound? otherwise this is really inefficient. let backtrace = std::backtrace::Backtrace::capture(); - self.span_delayed_bugs + self.delayed_bugs .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace)); - #[allow(deprecated)] return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } - DelayedBug(DelayedBugKind::GoodPath) => { + GoodPathDelayedBug => { let backtrace = std::backtrace::Backtrace::capture(); self.good_path_delayed_bugs .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace)); - return None; } Warning if !self.flags.can_emit_warnings => { @@ -1395,12 +1388,12 @@ impl DiagCtxtInner { fn flush_delayed(&mut self, kind: DelayedBugKind) { let (bugs, note1) = match kind { DelayedBugKind::Normal => ( - std::mem::take(&mut self.span_delayed_bugs), - "no errors encountered even though `span_delayed_bug` issued", + std::mem::take(&mut self.delayed_bugs), + "no errors encountered even though delayed bugs were created", ), DelayedBugKind::GoodPath => ( std::mem::take(&mut self.good_path_delayed_bugs), - "no warnings or errors encountered even though `good_path_delayed_bugs` issued", + "no warnings or errors encountered even though good path delayed bugs were created", ), }; let note2 = "those delayed bugs will now be shown as internal compiler errors"; @@ -1439,8 +1432,8 @@ impl DiagCtxtInner { let mut bug = if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner }; - // "Undelay" the `DelayedBug`s (into plain `Bug`s). - if !matches!(bug.level, DelayedBug(_)) { + // "Undelay" the delayed bugs (into plain `Bug`s). + if !matches!(bug.level, DelayedBug | GoodPathDelayedBug) { // NOTE(eddyb) not panicking here because we're already producing // an ICE, and the more information the merrier. bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel { @@ -1506,85 +1499,89 @@ impl DelayedDiagnostic { } } +/// Level is_error EmissionGuarantee Top-level Sub Lint-only +/// ----- -------- ----------------- --------- --- --------- +/// Bug yes BugAbort yes - - +/// Fatal yes FatalAbort/FatalError(*) yes - - +/// Error yes ErrorGuaranteed yes - - +/// DelayedBug yes ErrorGuaranteed yes - - +/// GoodPathDelayedBug - () yes - - +/// ForceWarning - () yes - yes +/// Warning - () yes yes - +/// Note - () rare yes - +/// OnceNote - () - rare - +/// Help - () rare yes - +/// OnceHelp - () - rare - +/// FailureNote - () rare - - +/// Allow - () yes - yes +/// Expect - () yes - yes +/// +/// (*) `FatalAbort` normally, `FatalError` in the non-aborting "almost fatal" case that is +/// occasionally used. +/// #[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)] pub enum Level { /// For bugs in the compiler. Manifests as an ICE (internal compiler error) panic. - /// - /// Its `EmissionGuarantee` is `BugAbort`. Bug, - /// This is a strange one: lets you register an error without emitting it. If compilation ends - /// without any other errors occurring, this will be emitted as a bug. Otherwise, it will be - /// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths - /// that should only be reached when compiling erroneous code. - /// - /// Its `EmissionGuarantee` is `ErrorGuaranteed` for `Normal` delayed bugs, and `()` for - /// `GoodPath` delayed bugs. - DelayedBug(DelayedBugKind), - /// An error that causes an immediate abort. Used for things like configuration errors, /// internal overflows, some file operation errors. - /// - /// Its `EmissionGuarantee` is `FatalAbort`, except in the non-aborting "almost fatal" case - /// that is occasionally used, where it is `FatalError`. Fatal, /// An error in the code being compiled, which prevents compilation from finishing. This is the /// most common case. - /// - /// Its `EmissionGuarantee` is `ErrorGuaranteed`. Error, + /// This is a strange one: lets you register an error without emitting it. If compilation ends + /// without any other errors occurring, this will be emitted as a bug. Otherwise, it will be + /// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths + /// that should only be reached when compiling erroneous code. + DelayedBug, + + /// Like `DelayedBug`, but weaker: lets you register an error without emitting it. If + /// compilation ends without any other diagnostics being emitted (and without an expected lint + /// being suppressed), this will be emitted as a bug. Otherwise, it will be silently dropped. + /// I.e. "expect other diagnostics are emitted (or suppressed)" semantics. Useful on code paths + /// that should only be reached when emitting diagnostics, e.g. for expensive one-time + /// diagnostic formatting operations. + /// + /// FIXME(nnethercote) good path delayed bugs are semantically strange: if printed they produce + /// an ICE, but they don't satisfy `is_error` and they don't guarantee an error is emitted. + /// Plus there's the extra complication with expected (suppressed) lints. They have limited + /// use, and are used in very few places, and "good path" isn't a good name. It would be good + /// to remove them. + GoodPathDelayedBug, + /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation /// from finishing. /// /// The [`LintExpectationId`] is used for expected lint diagnostics. In all other cases this /// should be `None`. - /// - /// Its `EmissionGuarantee` is `()`. ForceWarning(Option), /// A warning about the code being compiled. Does not prevent compilation from finishing. - /// - /// Its `EmissionGuarantee` is `()`. Warning, - /// A message giving additional context. Rare, because notes are more commonly attached to other - /// diagnostics such as errors. - /// - /// Its `EmissionGuarantee` is `()`. + /// A message giving additional context. Note, - /// A note that is only emitted once. Rare, mostly used in circumstances relating to lints. - /// - /// Its `EmissionGuarantee` is `()`. + /// A note that is only emitted once. OnceNote, - /// A message suggesting how to fix something. Rare, because help messages are more commonly - /// attached to other diagnostics such as errors. - /// - /// Its `EmissionGuarantee` is `()`. + /// A message suggesting how to fix something. Help, - /// A help that is only emitted once. Rare. - /// - /// Its `EmissionGuarantee` is `()`. + /// A help that is only emitted once. OnceHelp, /// Similar to `Note`, but used in cases where compilation has failed. When printed for human - /// consumption, it doesn't have any kind of `note:` label. Rare. - /// - /// Its `EmissionGuarantee` is `()`. + /// consumption, it doesn't have any kind of `note:` label. FailureNote, /// Only used for lints. - /// - /// Its `EmissionGuarantee` is `()`. Allow, /// Only used for lints. - /// - /// Its `EmissionGuarantee` is `()`. Expect(LintExpectationId), } @@ -1598,7 +1595,7 @@ impl Level { fn color(self) -> ColorSpec { let mut spec = ColorSpec::new(); match self { - Bug | DelayedBug(_) | Fatal | Error => { + Bug | Fatal | Error | DelayedBug | GoodPathDelayedBug => { spec.set_fg(Some(Color::Red)).set_intense(true); } ForceWarning(_) | Warning => { @@ -1618,7 +1615,7 @@ impl Level { pub fn to_str(self) -> &'static str { match self { - Bug | DelayedBug(_) => "error: internal compiler error", + Bug | DelayedBug | GoodPathDelayedBug => "error: internal compiler error", Fatal | Error => "error", ForceWarning(_) | Warning => "warning", Note | OnceNote => "note", @@ -1638,6 +1635,19 @@ impl Level { _ => None, } } + + // Can this level be used in a top-level diagnostic message and/or a + // subdiagnostic message? + fn can_be_top_or_sub(&self) -> (bool, bool) { + match self { + Bug | DelayedBug | Fatal | Error | GoodPathDelayedBug | ForceWarning(_) + | FailureNote | Allow | Expect(_) => (true, false), + + Warning | Note | Help => (true, true), + + OnceNote | OnceHelp => (false, true), + } + } } // FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite. diff --git a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr index 1011fc4163bca..0e3cd2ff06099 100644 --- a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr +++ b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr @@ -1,4 +1,4 @@ -note: no errors encountered even though `span_delayed_bug` issued +note: no errors encountered even though delayed bugs were created note: those delayed bugs will now be shown as internal compiler errors diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr index d92bafce142c2..fd76526644bdd 100644 --- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr @@ -1,4 +1,4 @@ -note: no errors encountered even though `span_delayed_bug` issued +note: no errors encountered even though delayed bugs were created note: those delayed bugs will now be shown as internal compiler errors From c4c22b0d52e9699edd02fd3a7a61965f296ba605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 24 Jan 2024 21:29:15 +0000 Subject: [PATCH 26/35] On E0277 be clearer about implicit `Sized` bounds on type params and assoc types ``` error[E0277]: the size for values of type `[i32]` cannot be known at compilation time --> f100.rs:2:33 | 2 | let _ = std::mem::size_of::<[i32]>(); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i32]` note: required by an implicit `Sized` bound in `std::mem::size_of` --> /home/gh-estebank/rust/library/core/src/mem/mod.rs:312:22 | 312 | pub const fn size_of() -> usize { | ^ required by the implicit `Sized` requirement on this bound in `size_of` ``` Fix #120178. --- .../rustc_hir_analysis/src/astconv/bounds.rs | 14 +- .../src/traits/error_reporting/suggestions.rs | 159 ++++++++++-------- tests/ui/associated-types/defaults-wf.stderr | 2 +- tests/ui/associated-types/issue-20005.stderr | 4 +- ...with-supertraits-needing-sized-self.stderr | 2 +- tests/ui/closures/issue-111932.stderr | 2 +- tests/ui/coroutine/sized-yield.stderr | 2 +- tests/ui/dst/dst-sized-trait-param.stderr | 4 +- tests/ui/extern/extern-types-unsized.stderr | 16 +- .../issue-88287.stderr | 4 +- ...e-param-can-reference-self-in-trait.stderr | 4 +- tests/ui/impl-trait/in-trait/wf-bounds.stderr | 8 +- tests/ui/issues/issue-10412.stderr | 4 +- tests/ui/issues/issue-18919.stderr | 4 +- tests/ui/issues/issue-20433.stderr | 2 +- tests/ui/issues/issue-23281.stderr | 4 +- tests/ui/issues/issue-87199.stderr | 4 +- tests/ui/iterators/collect-into-slice.rs | 2 +- tests/ui/iterators/collect-into-slice.stderr | 2 +- .../do-not-ice-on-note_and_explain.stderr | 4 +- tests/ui/methods/issues/issue-61525.stderr | 4 +- ...ect-safety-supertrait-mentions-Self.stderr | 4 +- tests/ui/range/range-1.stderr | 2 +- tests/ui/str/str-mut-idx.stderr | 4 +- ...adt-param-with-implicit-sized-bound.stderr | 20 +-- tests/ui/suggestions/bound-suggestions.stderr | 10 +- .../suggestions/issue-84973-blacklist.stderr | 4 +- ...unsized-indirection-in-where-clause.stderr | 4 +- ...re-clause-before-suggesting-unsized.stderr | 4 +- ...ltiline-trait-bound-in-where-clause.stderr | 12 +- tests/ui/trait-bounds/unsized-bound.stderr | 36 ++-- tests/ui/traits/bad-sized.stderr | 4 +- tests/ui/traits/issue-28576.stderr | 8 +- .../traits/issue-85360-eval-obligation-ice.rs | 2 - .../issue-85360-eval-obligation-ice.stderr | 22 +-- .../mutual-recursion-issue-75860.stderr | 2 +- tests/ui/traits/suggest-where-clause.stderr | 8 +- tests/ui/unsized/unsized-bare-typaram.stderr | 4 +- tests/ui/unsized/unsized-enum.stderr | 4 +- .../unsized-inherent-impl-self-type.stderr | 4 +- tests/ui/unsized/unsized-struct.stderr | 8 +- .../unsized-trait-impl-self-type.stderr | 4 +- .../unsized-trait-impl-trait-arg.stderr | 4 +- tests/ui/unsized/unsized3.stderr | 16 +- tests/ui/unsized/unsized7.stderr | 4 +- tests/ui/wf/hir-wf-canonicalized.stderr | 4 +- tests/ui/wf/wf-fn-where-clause.stderr | 4 +- tests/ui/wf/wf-impl-self-type.stderr | 2 +- 48 files changed, 232 insertions(+), 223 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index c22daad334fc5..e37119e7d4dc8 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -28,6 +28,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { let tcx = self.tcx(); let sized_def_id = tcx.lang_items().sized_trait(); let mut seen_negative_sized_bound = false; + let mut seen_positive_sized_bound = false; // Try to find an unbound in bounds. let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); @@ -45,6 +46,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { seen_negative_sized_bound = true; } } + hir::TraitBoundModifier::None => { + if let Some(sized_def_id) = sized_def_id + && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) + { + seen_positive_sized_bound = true; + } + } _ => {} } } @@ -82,11 +90,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { ); } - if seen_sized_unbound || seen_negative_sized_bound { - // There was in fact a `?Sized` or `!Sized` bound; + if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound { + // There was in fact a `?Sized`, `!Sized` or explicit `Sized` bound; // we don't need to do anything. } else if sized_def_id.is_some() { - // There was no `?Sized` or `!Sized` bound; + // There was no `?Sized`, `!Sized` or explicit `Sized` bound; // add `Sized` if it's available. bounds.push_sized(tcx, self_ty, span); } 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 5bab57ca56cb4..3060f33330e51 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3009,35 +3009,44 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); } } - let descr = format!("required by a bound in `{item_name}`"); - if span.is_visible(sm) { - let msg = format!("required by this bound in `{short_item_name}`"); - multispan.push_span_label(span, msg); - err.span_note(multispan, descr); - if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() - && let ty::ClauseKind::Trait(trait_pred) = clause - { - let def_id = trait_pred.def_id(); - let visible_item = if let Some(local) = def_id.as_local() { - // Check for local traits being reachable. - let vis = &tcx.resolutions(()).effective_visibilities; - // Account for non-`pub` traits in the root of the local crate. - let is_locally_reachable = tcx.parent(def_id).is_crate_root(); - vis.is_reachable(local) || is_locally_reachable - } else { - // Check for foreign traits being reachable. - tcx.visible_parent_map(()).get(&def_id).is_some() - }; - if Some(def_id) == tcx.lang_items().sized_trait() - && let Some(hir::Node::TraitItem(hir::TraitItem { - ident, - kind: hir::TraitItemKind::Type(bounds, None), - .. - })) = tcx.hir().get_if_local(item_def_id) - // Do not suggest relaxing if there is an explicit `Sized` obligation. - && !bounds.iter() - .filter_map(|bound| bound.trait_ref()) - .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait()) + let mut a = "a"; + let mut this = "this"; + let mut note = None; + let mut help = None; + if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() + && let ty::ClauseKind::Trait(trait_pred) = clause + { + let def_id = trait_pred.def_id(); + let visible_item = if let Some(local) = def_id.as_local() { + // Check for local traits being reachable. + let vis = &tcx.resolutions(()).effective_visibilities; + // Account for non-`pub` traits in the root of the local crate. + let is_locally_reachable = tcx.parent(def_id).is_crate_root(); + vis.is_reachable(local) || is_locally_reachable + } else { + // Check for foreign traits being reachable. + tcx.visible_parent_map(()).get(&def_id).is_some() + }; + if Some(def_id) == tcx.lang_items().sized_trait() { + // Check if this is an implicit bound, even in foreign crates. + if tcx + .generics_of(item_def_id) + .params + .iter() + .any(|param| tcx.def_span(param.def_id) == span) + { + a = "an implicit `Sized`"; + this = "the implicit `Sized` requirement on this"; + } + if let Some(hir::Node::TraitItem(hir::TraitItem { + ident, + kind: hir::TraitItemKind::Type(bounds, None), + .. + })) = tcx.hir().get_if_local(item_def_id) + // Do not suggest relaxing if there is an explicit `Sized` obligation. + && !bounds.iter() + .filter_map(|bound| bound.trait_ref()) + .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait()) { let (span, separator) = if let [.., last] = bounds { (last.span().shrink_to_hi(), " +") @@ -3051,52 +3060,64 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { Applicability::MachineApplicable, ); } - if let DefKind::Trait = tcx.def_kind(item_def_id) - && !visible_item - { - err.note(format!( - "`{short_item_name}` is a \"sealed trait\", because to implement \ - it you also need to implement `{}`, which is not accessible; \ - this is usually done to force you to use one of the provided \ - 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()) + } + if let DefKind::Trait = tcx.def_kind(item_def_id) + && !visible_item + { + note = Some(format!( + "`{short_item_name}` is a \"sealed trait\", because to implement it \ + you also need to implement `{}`, which is not accessible; this is \ + usually done to force you to use one of the provided 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::>(); - 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"), - )); - } + let post = if types.len() > 9 { + types.truncate(8); + format!("\nand {} others", len - 8) + } else { + String::new() + }; + help = Some(format!( + "the following type{} implement{} the trait:\n{}{post}", + pluralize!(len), + if len == 1 { "s" } else { "" }, + types.join("\n"), + )); } } + }; + let descr = format!("required by {a} bound in `{item_name}`"); + if span.is_visible(sm) { + let msg = format!("required by {this} bound in `{short_item_name}`"); + multispan.push_span_label(span, msg); + err.span_note(multispan, descr); } else { err.span_note(tcx.def_span(item_def_id), descr); } + if let Some(note) = note { + err.note(note); + } + if let Some(help) = help { + err.help(help); + } } ObligationCauseCode::Coercion { source, target } => { let mut file = None; diff --git a/tests/ui/associated-types/defaults-wf.stderr b/tests/ui/associated-types/defaults-wf.stderr index aeb4e47abcbf7..f0b10189bd8d9 100644 --- a/tests/ui/associated-types/defaults-wf.stderr +++ b/tests/ui/associated-types/defaults-wf.stderr @@ -5,7 +5,7 @@ LL | type Ty = Vec<[u8]>; | ^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Vec` +note: required by an implicit `Sized` bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/issue-20005.stderr b/tests/ui/associated-types/issue-20005.stderr index 02470a4424919..ce3f556f2d744 100644 --- a/tests/ui/associated-types/issue-20005.stderr +++ b/tests/ui/associated-types/issue-20005.stderr @@ -4,11 +4,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | ) -> >::Result where Dst: From { | ^^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `From` +note: required by an implicit `Sized` bound in `From` --> $DIR/issue-20005.rs:1:12 | LL | trait From { - | ^^^ required by this bound in `From` + | ^^^ required by the implicit `Sized` requirement on this bound in `From` help: consider further restricting `Self` | LL | ) -> >::Result where Dst: From, Self: Sized { diff --git a/tests/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr b/tests/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr index 99a46dedcdce6..8154441411323 100644 --- a/tests/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr +++ b/tests/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr @@ -4,7 +4,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | trait ArithmeticOps: Add + Sub + Mul + Div {} | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `Add` +note: required by an implicit `Sized` bound in `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: consider further restricting `Self` | diff --git a/tests/ui/closures/issue-111932.stderr b/tests/ui/closures/issue-111932.stderr index 937bdf3bea255..ff46b10d005dc 100644 --- a/tests/ui/closures/issue-111932.stderr +++ b/tests/ui/closures/issue-111932.stderr @@ -17,7 +17,7 @@ LL | println!("{:?}", foo); | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `dyn Foo` -note: required by a bound in `core::fmt::rt::Argument::<'a>::new_debug` +note: required by an implicit `Sized` bound in `core::fmt::rt::Argument::<'a>::new_debug` --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/coroutine/sized-yield.stderr b/tests/ui/coroutine/sized-yield.stderr index bbecaffa95a12..4e8dc13201de3 100644 --- a/tests/ui/coroutine/sized-yield.stderr +++ b/tests/ui/coroutine/sized-yield.stderr @@ -18,7 +18,7 @@ LL | Pin::new(&mut gen).resume(()); | ^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` -note: required by a bound in `CoroutineState` +note: required by an implicit `Sized` bound in `CoroutineState` --> $SRC_DIR/core/src/ops/coroutine.rs:LL:COL error: aborting due to 2 previous errors diff --git a/tests/ui/dst/dst-sized-trait-param.stderr b/tests/ui/dst/dst-sized-trait-param.stderr index 60e9de90332cc..a3a686dced217 100644 --- a/tests/ui/dst/dst-sized-trait-param.stderr +++ b/tests/ui/dst/dst-sized-trait-param.stderr @@ -5,11 +5,11 @@ LL | impl Foo<[isize]> for usize { } | ^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[isize]` -note: required by a bound in `Foo` +note: required by an implicit `Sized` bound in `Foo` --> $DIR/dst-sized-trait-param.rs:5:11 | LL | trait Foo : Sized { fn take(self, x: &T) { } } // Note: T is sized - | ^ required by this bound in `Foo` + | ^ required by the implicit `Sized` requirement on this bound in `Foo` help: consider relaxing the implicit `Sized` restriction | LL | trait Foo : Sized { fn take(self, x: &T) { } } // Note: T is sized diff --git a/tests/ui/extern/extern-types-unsized.stderr b/tests/ui/extern/extern-types-unsized.stderr index 0ae33e25b811e..6592724a53e70 100644 --- a/tests/ui/extern/extern-types-unsized.stderr +++ b/tests/ui/extern/extern-types-unsized.stderr @@ -5,11 +5,11 @@ LL | assert_sized::(); | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `A` -note: required by a bound in `assert_sized` +note: required by an implicit `Sized` bound in `assert_sized` --> $DIR/extern-types-unsized.rs:19:17 | LL | fn assert_sized() {} - | ^ required by this bound in `assert_sized` + | ^ required by the implicit `Sized` requirement on this bound in `assert_sized` help: consider relaxing the implicit `Sized` restriction | LL | fn assert_sized() {} @@ -27,11 +27,11 @@ note: required because it appears within the type `Foo` | LL | struct Foo { | ^^^ -note: required by a bound in `assert_sized` +note: required by an implicit `Sized` bound in `assert_sized` --> $DIR/extern-types-unsized.rs:19:17 | LL | fn assert_sized() {} - | ^ required by this bound in `assert_sized` + | ^ required by the implicit `Sized` requirement on this bound in `assert_sized` help: consider relaxing the implicit `Sized` restriction | LL | fn assert_sized() {} @@ -49,11 +49,11 @@ note: required because it appears within the type `Bar` | LL | struct Bar { | ^^^ -note: required by a bound in `assert_sized` +note: required by an implicit `Sized` bound in `assert_sized` --> $DIR/extern-types-unsized.rs:19:17 | LL | fn assert_sized() {} - | ^ required by this bound in `assert_sized` + | ^ required by the implicit `Sized` requirement on this bound in `assert_sized` help: consider relaxing the implicit `Sized` restriction | LL | fn assert_sized() {} @@ -71,11 +71,11 @@ note: required because it appears within the type `Bar` | LL | struct Bar { | ^^^ -note: required by a bound in `assert_sized` +note: required by an implicit `Sized` bound in `assert_sized` --> $DIR/extern-types-unsized.rs:19:17 | LL | fn assert_sized() {} - | ^ required by this bound in `assert_sized` + | ^ required by the implicit `Sized` requirement on this bound in `assert_sized` help: consider relaxing the implicit `Sized` restriction | LL | fn assert_sized() {} diff --git a/tests/ui/generic-associated-types/issue-88287.stderr b/tests/ui/generic-associated-types/issue-88287.stderr index 79ac6d0f10bd2..6b26223dd5144 100644 --- a/tests/ui/generic-associated-types/issue-88287.stderr +++ b/tests/ui/generic-associated-types/issue-88287.stderr @@ -7,11 +7,11 @@ LL | type SearchFutureTy<'f, A, B: 'f> LL | async move { todo!() } | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `>` +note: required by an implicit `Sized` bound in `>` --> $DIR/issue-88287.rs:24:6 | LL | impl SearchableResourceExt for T - | ^ required by this bound in `>` + | ^ required by the implicit `Sized` requirement on this bound in `>` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - A: SearchableResource + ?Sized + 'f, diff --git a/tests/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr b/tests/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr index 3f4f50562e252..3739829455bde 100644 --- a/tests/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr +++ b/tests/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr @@ -6,10 +6,10 @@ LL | impl Tsized for () {} | = help: the trait `Sized` is not implemented for `[()]` note: required by a bound in `Tsized` - --> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:17:14 + --> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:17:17 | LL | trait Tsized {} - | ^^^^^^^^^^^^^^^^^ required by this bound in `Tsized` + | ^^^^^ required by this bound in `Tsized` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.stderr index c20df9b40edfb..e2e06ba4e5ae8 100644 --- a/tests/ui/impl-trait/in-trait/wf-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/wf-bounds.stderr @@ -5,7 +5,7 @@ LL | fn nya() -> impl Wf>; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Vec` +note: required by an implicit `Sized` bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0277]: the size for values of type `[u8]` cannot be known at compilation time @@ -15,11 +15,11 @@ LL | fn nya2() -> impl Wf<[u8]>; | ^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Wf` +note: required by an implicit `Sized` bound in `Wf` --> $DIR/wf-bounds.rs:7:10 | LL | trait Wf { - | ^ required by this bound in `Wf` + | ^ required by the implicit `Sized` requirement on this bound in `Wf` help: consider relaxing the implicit `Sized` restriction | LL | trait Wf { @@ -32,7 +32,7 @@ LL | fn nya3() -> impl Wf<(), Output = impl Wf>>; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Vec` +note: required by an implicit `Sized` bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0277]: `T` doesn't implement `std::fmt::Display` diff --git a/tests/ui/issues/issue-10412.stderr b/tests/ui/issues/issue-10412.stderr index 26666782d2abc..dcf7769264b22 100644 --- a/tests/ui/issues/issue-10412.stderr +++ b/tests/ui/issues/issue-10412.stderr @@ -58,11 +58,11 @@ LL | impl<'self> Serializable for &'self str { | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` -note: required by a bound in `Serializable` +note: required by an implicit `Sized` bound in `Serializable` --> $DIR/issue-10412.rs:1:27 | LL | trait Serializable<'self, T> { - | ^ required by this bound in `Serializable` + | ^ required by the implicit `Sized` requirement on this bound in `Serializable` help: consider relaxing the implicit `Sized` restriction | LL | trait Serializable<'self, T: ?Sized> { diff --git a/tests/ui/issues/issue-18919.stderr b/tests/ui/issues/issue-18919.stderr index 6dcd891cedac9..471b5d5bdf12a 100644 --- a/tests/ui/issues/issue-18919.stderr +++ b/tests/ui/issues/issue-18919.stderr @@ -5,11 +5,11 @@ LL | fn ho_func(f: Option) { | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `dyn for<'a> Fn(&'a isize) -> isize` -note: required by a bound in `Option` +note: required by an implicit `Sized` bound in `Option` --> $DIR/issue-18919.rs:7:13 | LL | enum Option { - | ^ required by this bound in `Option` + | ^ required by the implicit `Sized` requirement on this bound in `Option` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/issue-18919.rs:7:13 | diff --git a/tests/ui/issues/issue-20433.stderr b/tests/ui/issues/issue-20433.stderr index 2dd0b3c2f8439..3730a67cc7959 100644 --- a/tests/ui/issues/issue-20433.stderr +++ b/tests/ui/issues/issue-20433.stderr @@ -5,7 +5,7 @@ LL | fn iceman(c: Vec<[i32]>) {} | ^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i32]` -note: required by a bound in `Vec` +note: required by an implicit `Sized` bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-23281.stderr b/tests/ui/issues/issue-23281.stderr index e1f4e8a96c825..4c25d1efedd6a 100644 --- a/tests/ui/issues/issue-23281.stderr +++ b/tests/ui/issues/issue-23281.stderr @@ -5,11 +5,11 @@ LL | pub fn function(funs: Vec ()>) {} | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Fn() + 'static)` -note: required by a bound in `Vec` +note: required by an implicit `Sized` bound in `Vec` --> $DIR/issue-23281.rs:8:12 | LL | struct Vec { - | ^ required by this bound in `Vec` + | ^ required by the implicit `Sized` requirement on this bound in `Vec` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/issue-23281.rs:8:12 | diff --git a/tests/ui/issues/issue-87199.stderr b/tests/ui/issues/issue-87199.stderr index d81bc3615575e..6c4fbddb04924 100644 --- a/tests/ui/issues/issue-87199.stderr +++ b/tests/ui/issues/issue-87199.stderr @@ -23,11 +23,11 @@ LL | ref_arg::<[i32]>(&[5]); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i32]` -note: required by a bound in `ref_arg` +note: required by an implicit `Sized` bound in `ref_arg` --> $DIR/issue-87199.rs:10:12 | LL | fn ref_arg(_: &T) {} - | ^ required by this bound in `ref_arg` + | ^ required by the implicit `Sized` requirement on this bound in `ref_arg` help: consider relaxing the implicit `Sized` restriction | LL | fn ref_arg(_: &T) {} diff --git a/tests/ui/iterators/collect-into-slice.rs b/tests/ui/iterators/collect-into-slice.rs index 045d40a6f71ae..120e56a6549e4 100644 --- a/tests/ui/iterators/collect-into-slice.rs +++ b/tests/ui/iterators/collect-into-slice.rs @@ -8,7 +8,7 @@ fn main() { //~| ERROR the size for values of type `[i32]` cannot be known at compilation time //~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size //~| NOTE try explicitly collecting into a `Vec<{integer}>` - //~| NOTE required by a bound in `collect` + //~| NOTE required by an implicit `Sized` bound in `collect` //~| NOTE required by a bound in `collect` //~| NOTE all local variables must have a statically known size //~| NOTE doesn't have a size known at compile-time diff --git a/tests/ui/iterators/collect-into-slice.stderr b/tests/ui/iterators/collect-into-slice.stderr index 45685ef0ce9cd..56f1bf770607e 100644 --- a/tests/ui/iterators/collect-into-slice.stderr +++ b/tests/ui/iterators/collect-into-slice.stderr @@ -25,7 +25,7 @@ LL | let some_generated_vec = (0..10).collect(); | ^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i32]` -note: required by a bound in `collect` +note: required by an implicit `Sized` bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error[E0277]: a slice of type `&[i32]` cannot be built since we need to store the elements somewhere diff --git a/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr b/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr index 27b86145e90f4..47c01b9e805d8 100644 --- a/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr +++ b/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr @@ -60,11 +60,11 @@ LL | implA{fn d(){fn d(){Self(1)}}} | | | this type parameter needs to be `Sized` | -note: required by a bound in `A` +note: required by an implicit `Sized` bound in `A` --> $DIR/do-not-ice-on-note_and_explain.rs:1:10 | LL | struct A(B); - | ^ required by this bound in `A` + | ^ required by the implicit `Sized` requirement on this bound in `A` help: you could relax the implicit `Sized` bound on `B` if it were used through indirection like `&B` or `Box` --> $DIR/do-not-ice-on-note_and_explain.rs:1:10 | diff --git a/tests/ui/methods/issues/issue-61525.stderr b/tests/ui/methods/issues/issue-61525.stderr index 2670a3e4755b1..777d0b4f3d125 100644 --- a/tests/ui/methods/issues/issue-61525.stderr +++ b/tests/ui/methods/issues/issue-61525.stderr @@ -7,11 +7,11 @@ LL | 1.query::("") | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `dyn ToString` -note: required by a bound in `Example::query` +note: required by an implicit `Sized` bound in `Example::query` --> $DIR/issue-61525.rs:2:14 | LL | fn query(self, q: Q); - | ^ required by this bound in `Example::query` + | ^ required by the implicit `Sized` requirement on this bound in `Example::query` help: consider relaxing the implicit `Sized` restriction | LL | fn query(self, q: Q); diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr index 22adc19c8029f..2380cba89486f 100644 --- a/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr +++ b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr @@ -22,11 +22,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | trait Baz : Bar { | ^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `Bar` +note: required by an implicit `Sized` bound in `Bar` --> $DIR/object-safety-supertrait-mentions-Self.rs:4:11 | LL | trait Bar { - | ^ required by this bound in `Bar` + | ^ required by the implicit `Sized` requirement on this bound in `Bar` help: consider further restricting `Self` | LL | trait Baz : Bar + Sized { diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr index 569f700cf10ba..3d9b7a940b7c8 100644 --- a/tests/ui/range/range-1.stderr +++ b/tests/ui/range/range-1.stderr @@ -30,7 +30,7 @@ LL | let range = *arr..; | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[{integer}]` -note: required by a bound in `RangeFrom` +note: required by an implicit `Sized` bound in `RangeFrom` --> $SRC_DIR/core/src/ops/range.rs:LL:COL error: aborting due to 3 previous errors diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index 17a75bf8c2ae6..5a2664f4522e8 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -5,11 +5,11 @@ LL | s[1..2] = bot(); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` -note: required by a bound in `bot` +note: required by an implicit `Sized` bound in `bot` --> $DIR/str-mut-idx.rs:1:8 | LL | fn bot() -> T { loop {} } - | ^ required by this bound in `bot` + | ^ required by the implicit `Sized` requirement on this bound in `bot` help: consider relaxing the implicit `Sized` restriction | LL | fn bot() -> T { loop {} } diff --git a/tests/ui/suggestions/adt-param-with-implicit-sized-bound.stderr b/tests/ui/suggestions/adt-param-with-implicit-sized-bound.stderr index d136f5ff6543f..705f078c367d0 100644 --- a/tests/ui/suggestions/adt-param-with-implicit-sized-bound.stderr +++ b/tests/ui/suggestions/adt-param-with-implicit-sized-bound.stderr @@ -6,11 +6,11 @@ LL | struct Struct5{ LL | _t: X, | ^^^^ doesn't have a size known at compile-time | -note: required by a bound in `X` +note: required by an implicit `Sized` bound in `X` --> $DIR/adt-param-with-implicit-sized-bound.rs:18:10 | LL | struct X(T); - | ^ required by this bound in `X` + | ^ required by the implicit `Sized` requirement on this bound in `X` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/adt-param-with-implicit-sized-bound.rs:18:10 | @@ -30,11 +30,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | fn func1() -> Struct1; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `Struct1` +note: required by an implicit `Sized` bound in `Struct1` --> $DIR/adt-param-with-implicit-sized-bound.rs:8:16 | LL | struct Struct1{ - | ^ required by this bound in `Struct1` + | ^ required by the implicit `Sized` requirement on this bound in `Struct1` help: consider further restricting `Self` | LL | fn func1() -> Struct1 where Self: Sized; @@ -50,11 +50,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | fn func2<'a>() -> Struct2<'a, Self>; | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `Struct2` +note: required by an implicit `Sized` bound in `Struct2` --> $DIR/adt-param-with-implicit-sized-bound.rs:11:20 | LL | struct Struct2<'a, T>{ - | ^ required by this bound in `Struct2` + | ^ required by the implicit `Sized` requirement on this bound in `Struct2` help: consider further restricting `Self` | LL | fn func2<'a>() -> Struct2<'a, Self> where Self: Sized; @@ -70,11 +70,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | fn func3() -> Struct3; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `Struct3` +note: required by an implicit `Sized` bound in `Struct3` --> $DIR/adt-param-with-implicit-sized-bound.rs:14:16 | LL | struct Struct3{ - | ^ required by this bound in `Struct3` + | ^ required by the implicit `Sized` requirement on this bound in `Struct3` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/adt-param-with-implicit-sized-bound.rs:14:16 | @@ -93,11 +93,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | fn func4() -> Struct4; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `Struct4` +note: required by an implicit `Sized` bound in `Struct4` --> $DIR/adt-param-with-implicit-sized-bound.rs:20:16 | LL | struct Struct4{ - | ^ required by this bound in `Struct4` + | ^ required by the implicit `Sized` requirement on this bound in `Struct4` help: consider further restricting `Self` | LL | fn func4() -> Struct4 where Self: Sized; diff --git a/tests/ui/suggestions/bound-suggestions.stderr b/tests/ui/suggestions/bound-suggestions.stderr index cd27947f02fad..7e58ccd461d19 100644 --- a/tests/ui/suggestions/bound-suggestions.stderr +++ b/tests/ui/suggestions/bound-suggestions.stderr @@ -76,7 +76,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | const SIZE: usize = core::mem::size_of::(); | ^^^^ doesn't have a size known at compile-time | -note: required by a bound in `std::mem::size_of` +note: required by an implicit `Sized` bound in `std::mem::size_of` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL help: consider further restricting `Self` | @@ -89,7 +89,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | const SIZE: usize = core::mem::size_of::(); | ^^^^ doesn't have a size known at compile-time | -note: required by a bound in `std::mem::size_of` +note: required by an implicit `Sized` bound in `std::mem::size_of` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL help: consider further restricting `Self` | @@ -102,7 +102,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | const SIZE: usize = core::mem::size_of::(); | ^^^^ doesn't have a size known at compile-time | -note: required by a bound in `std::mem::size_of` +note: required by an implicit `Sized` bound in `std::mem::size_of` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL help: consider further restricting `Self` | @@ -115,7 +115,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | const SIZE: usize = core::mem::size_of::(); | ^^^^ doesn't have a size known at compile-time | -note: required by a bound in `std::mem::size_of` +note: required by an implicit `Sized` bound in `std::mem::size_of` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL help: consider further restricting `Self` | @@ -128,7 +128,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | const SIZE: usize = core::mem::size_of::(); | ^^^^ doesn't have a size known at compile-time | -note: required by a bound in `std::mem::size_of` +note: required by an implicit `Sized` bound in `std::mem::size_of` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL help: consider further restricting `Self` | diff --git a/tests/ui/suggestions/issue-84973-blacklist.stderr b/tests/ui/suggestions/issue-84973-blacklist.stderr index e0bdb6949a9c9..8e980997089e6 100644 --- a/tests/ui/suggestions/issue-84973-blacklist.stderr +++ b/tests/ui/suggestions/issue-84973-blacklist.stderr @@ -57,10 +57,10 @@ LL | f_sized(*ref_cl); | = help: the trait `Sized` is not implemented for `dyn Fn()` note: required by a bound in `f_sized` - --> $DIR/issue-84973-blacklist.rs:9:12 + --> $DIR/issue-84973-blacklist.rs:9:15 | LL | fn f_sized(t: T) {} - | ^ required by this bound in `f_sized` + | ^^^^^ required by this bound in `f_sized` error[E0277]: `Rc<{integer}>` cannot be sent between threads safely --> $DIR/issue-84973-blacklist.rs:27:12 diff --git a/tests/ui/suggestions/issue-85943-no-suggest-unsized-indirection-in-where-clause.stderr b/tests/ui/suggestions/issue-85943-no-suggest-unsized-indirection-in-where-clause.stderr index 21b568b02ad25..e2f1532cc4eaf 100644 --- a/tests/ui/suggestions/issue-85943-no-suggest-unsized-indirection-in-where-clause.stderr +++ b/tests/ui/suggestions/issue-85943-no-suggest-unsized-indirection-in-where-clause.stderr @@ -5,11 +5,11 @@ LL | struct B(A<[u8]>); | ^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `A` +note: required by an implicit `Sized` bound in `A` --> $DIR/issue-85943-no-suggest-unsized-indirection-in-where-clause.rs:4:10 | LL | struct A(T) where T: Send; - | ^ required by this bound in `A` + | ^ required by the implicit `Sized` requirement on this bound in `A` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/issue-85943-no-suggest-unsized-indirection-in-where-clause.rs:4:10 | diff --git a/tests/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.stderr b/tests/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.stderr index 77e5dcd91a1ea..1cbcfbf84bcf4 100644 --- a/tests/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.stderr +++ b/tests/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.stderr @@ -8,10 +8,10 @@ LL | fn bar() { foo(""); } | = help: the trait `Sized` is not implemented for `str` note: required by a bound in `foo` - --> $DIR/issue-85945-check-where-clause-before-suggesting-unsized.rs:3:8 + --> $DIR/issue-85945-check-where-clause-before-suggesting-unsized.rs:3:27 | LL | fn foo(_: &T) where T: Sized {} - | ^ required by this bound in `foo` + | ^^^^^ required by this bound in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/removal-of-multiline-trait-bound-in-where-clause.stderr b/tests/ui/suggestions/removal-of-multiline-trait-bound-in-where-clause.stderr index eb74679d66049..7d20120654af3 100644 --- a/tests/ui/suggestions/removal-of-multiline-trait-bound-in-where-clause.stderr +++ b/tests/ui/suggestions/removal-of-multiline-trait-bound-in-where-clause.stderr @@ -6,11 +6,11 @@ LL | fn foo(foo: Wrapper) | | | this type parameter needs to be `Sized` | -note: required by a bound in `Wrapper` +note: required by an implicit `Sized` bound in `Wrapper` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | LL | struct Wrapper(T); - | ^ required by this bound in `Wrapper` + | ^ required by the implicit `Sized` requirement on this bound in `Wrapper` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | @@ -35,11 +35,11 @@ LL | fn bar(foo: Wrapper) | | | this type parameter needs to be `Sized` | -note: required by a bound in `Wrapper` +note: required by an implicit `Sized` bound in `Wrapper` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | LL | struct Wrapper(T); - | ^ required by this bound in `Wrapper` + | ^ required by the implicit `Sized` requirement on this bound in `Wrapper` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | @@ -60,11 +60,11 @@ LL | fn qux(foo: Wrapper) | | | this type parameter needs to be `Sized` | -note: required by a bound in `Wrapper` +note: required by an implicit `Sized` bound in `Wrapper` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | LL | struct Wrapper(T); - | ^ required by this bound in `Wrapper` + | ^ required by the implicit `Sized` requirement on this bound in `Wrapper` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | diff --git a/tests/ui/trait-bounds/unsized-bound.stderr b/tests/ui/trait-bounds/unsized-bound.stderr index 4d45bffabce5e..87a43a6fddab0 100644 --- a/tests/ui/trait-bounds/unsized-bound.stderr +++ b/tests/ui/trait-bounds/unsized-bound.stderr @@ -7,11 +7,11 @@ LL | impl Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} | this type parameter needs to be `Sized` | = note: required because it appears within the type `(A, B)` -note: required by a bound in `Trait` +note: required by an implicit `Sized` bound in `Trait` --> $DIR/unsized-bound.rs:1:13 | LL | trait Trait {} - | ^ required by this bound in `Trait` + | ^ required by the implicit `Sized` requirement on this bound in `Trait` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} @@ -46,11 +46,11 @@ LL | impl Trait<(A, B, C)> for (A, B, C) where A: ?Size | this type parameter needs to be `Sized` | = note: required because it appears within the type `(A, B, C)` -note: required by a bound in `Trait` +note: required by an implicit `Sized` bound in `Trait` --> $DIR/unsized-bound.rs:1:13 | LL | trait Trait {} - | ^ required by this bound in `Trait` + | ^ required by the implicit `Sized` requirement on this bound in `Trait` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} @@ -96,11 +96,11 @@ LL | impl Trait2<(A, B)> for (A, B) {} | this type parameter needs to be `Sized` | = note: required because it appears within the type `(A, B)` -note: required by a bound in `Trait2` +note: required by an implicit `Sized` bound in `Trait2` --> $DIR/unsized-bound.rs:9:14 | LL | trait Trait2 {} - | ^ required by this bound in `Trait2` + | ^ required by the implicit `Sized` requirement on this bound in `Trait2` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait2<(A, B)> for (A, B) {} @@ -134,11 +134,11 @@ LL | impl Trait3 for A where A: ?Sized {} | | | this type parameter needs to be `Sized` | -note: required by a bound in `Trait3` +note: required by an implicit `Sized` bound in `Trait3` --> $DIR/unsized-bound.rs:13:14 | LL | trait Trait3 {} - | ^ required by this bound in `Trait3` + | ^ required by the implicit `Sized` requirement on this bound in `Trait3` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait3 for A where A: ?Sized {} @@ -157,11 +157,11 @@ LL | impl Trait4 for A {} | | | this type parameter needs to be `Sized` | -note: required by a bound in `Trait4` +note: required by an implicit `Sized` bound in `Trait4` --> $DIR/unsized-bound.rs:16:14 | LL | trait Trait4 {} - | ^ required by this bound in `Trait4` + | ^ required by the implicit `Sized` requirement on this bound in `Trait4` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait4 for A {} @@ -180,11 +180,11 @@ LL | impl Trait5 for X where X: ?Sized {} | | | this type parameter needs to be `Sized` | -note: required by a bound in `Trait5` +note: required by an implicit `Sized` bound in `Trait5` --> $DIR/unsized-bound.rs:19:14 | LL | trait Trait5 {} - | ^ required by this bound in `Trait5` + | ^ required by the implicit `Sized` requirement on this bound in `Trait5` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait5 for X where X: ?Sized {} @@ -203,11 +203,11 @@ LL | impl Trait6 for X {} | | | this type parameter needs to be `Sized` | -note: required by a bound in `Trait6` +note: required by an implicit `Sized` bound in `Trait6` --> $DIR/unsized-bound.rs:22:14 | LL | trait Trait6 {} - | ^ required by this bound in `Trait6` + | ^ required by the implicit `Sized` requirement on this bound in `Trait6` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait6 for X {} @@ -226,11 +226,11 @@ LL | impl Trait7 for X where Y: ?Sized {} | | | this type parameter needs to be `Sized` | -note: required by a bound in `Trait7` +note: required by an implicit `Sized` bound in `Trait7` --> $DIR/unsized-bound.rs:25:17 | LL | trait Trait7 {} - | ^ required by this bound in `Trait7` + | ^ required by the implicit `Sized` requirement on this bound in `Trait7` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait7 for X where Y: ?Sized {} @@ -249,11 +249,11 @@ LL | impl Trait8 for X {} | | | this type parameter needs to be `Sized` | -note: required by a bound in `Trait8` +note: required by an implicit `Sized` bound in `Trait8` --> $DIR/unsized-bound.rs:28:17 | LL | trait Trait8 {} - | ^ required by this bound in `Trait8` + | ^ required by the implicit `Sized` requirement on this bound in `Trait8` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait8 for X {} diff --git a/tests/ui/traits/bad-sized.stderr b/tests/ui/traits/bad-sized.stderr index 857495f4a156d..4c1835dfed085 100644 --- a/tests/ui/traits/bad-sized.stderr +++ b/tests/ui/traits/bad-sized.stderr @@ -16,7 +16,7 @@ LL | let x: Vec = Vec::new(); | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `dyn Trait` -note: required by a bound in `Vec` +note: required by an implicit `Sized` bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time @@ -36,7 +36,7 @@ LL | let x: Vec = Vec::new(); | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `dyn Trait` -note: required by a bound in `Vec` +note: required by an implicit `Sized` bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error: aborting due to 4 previous errors diff --git a/tests/ui/traits/issue-28576.stderr b/tests/ui/traits/issue-28576.stderr index 96e8aaee23d56..dc08f9f6ccd4c 100644 --- a/tests/ui/traits/issue-28576.stderr +++ b/tests/ui/traits/issue-28576.stderr @@ -25,11 +25,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | pub trait Bar: Foo { | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `Foo` +note: required by an implicit `Sized` bound in `Foo` --> $DIR/issue-28576.rs:1:15 | LL | pub trait Foo { - | ^^^^^^^^ required by this bound in `Foo` + | ^^^^^^^^ required by the implicit `Sized` requirement on this bound in `Foo` help: consider further restricting `Self` | LL | pub trait Bar: Foo + Sized { @@ -45,11 +45,11 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | pub trait Bar: Foo { | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -note: required by a bound in `Foo` +note: required by an implicit `Sized` bound in `Foo` --> $DIR/issue-28576.rs:1:15 | LL | pub trait Foo { - | ^^^^^^^^ required by this bound in `Foo` + | ^^^^^^^^ required by the implicit `Sized` requirement on this bound in `Foo` help: consider further restricting `Self` | LL | ) where Self: Sized; diff --git a/tests/ui/traits/issue-85360-eval-obligation-ice.rs b/tests/ui/traits/issue-85360-eval-obligation-ice.rs index ac8bda9c01042..75483a810949d 100644 --- a/tests/ui/traits/issue-85360-eval-obligation-ice.rs +++ b/tests/ui/traits/issue-85360-eval-obligation-ice.rs @@ -8,11 +8,9 @@ use core::marker::PhantomData; fn main() { test::>>(make()); //~^ ERROR evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk) - //~| ERROR evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk) test::>>(make()); //~^ ERROR evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions) - //~| ERROR evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions) } #[rustc_evaluate_where_clauses] diff --git a/tests/ui/traits/issue-85360-eval-obligation-ice.stderr b/tests/ui/traits/issue-85360-eval-obligation-ice.stderr index 9590ea12c05e4..d2b00a45a4f15 100644 --- a/tests/ui/traits/issue-85360-eval-obligation-ice.stderr +++ b/tests/ui/traits/issue-85360-eval-obligation-ice.stderr @@ -1,12 +1,3 @@ -error: evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk) - --> $DIR/issue-85360-eval-obligation-ice.rs:9:5 - | -LL | test::>>(make()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | fn test(_: T) {} - | - predicate - error: evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk) --> $DIR/issue-85360-eval-obligation-ice.rs:9:5 | @@ -17,16 +8,7 @@ LL | fn test(_: T) {} | ----- predicate error: evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions) - --> $DIR/issue-85360-eval-obligation-ice.rs:13:5 - | -LL | test::>>(make()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | fn test(_: T) {} - | - predicate - -error: evaluate(Binder { value: TraitPredicate(> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions) - --> $DIR/issue-85360-eval-obligation-ice.rs:13:5 + --> $DIR/issue-85360-eval-obligation-ice.rs:12:5 | LL | test::>>(make()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,5 +16,5 @@ LL | test::>>(make()); LL | fn test(_: T) {} | ----- predicate -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/traits/mutual-recursion-issue-75860.stderr b/tests/ui/traits/mutual-recursion-issue-75860.stderr index 420ed2dcd2f09..8f83bab003db3 100644 --- a/tests/ui/traits/mutual-recursion-issue-75860.stderr +++ b/tests/ui/traits/mutual-recursion-issue-75860.stderr @@ -5,7 +5,7 @@ LL | iso(left, right) | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`mutual_recursion_issue_75860`) -note: required by a bound in `Option` +note: required by an implicit `Sized` bound in `Option` --> $SRC_DIR/core/src/option.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/traits/suggest-where-clause.stderr b/tests/ui/traits/suggest-where-clause.stderr index e3bbf768c6e73..08f3a8dc23dd1 100644 --- a/tests/ui/traits/suggest-where-clause.stderr +++ b/tests/ui/traits/suggest-where-clause.stderr @@ -7,7 +7,7 @@ LL | // suggest a where-clause, if needed LL | mem::size_of::(); | ^ doesn't have a size known at compile-time | -note: required by a bound in `std::mem::size_of` +note: required by an implicit `Sized` bound in `std::mem::size_of` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL help: consider removing the `?Sized` bound to make the type parameter `Sized` | @@ -29,7 +29,7 @@ note: required because it appears within the type `Misc` | LL | struct Misc(T); | ^^^^ -note: required by a bound in `std::mem::size_of` +note: required by an implicit `Sized` bound in `std::mem::size_of` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL help: consider removing the `?Sized` bound to make the type parameter `Sized` | @@ -72,7 +72,7 @@ LL | mem::size_of::<[T]>(); | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[T]` -note: required by a bound in `std::mem::size_of` +note: required by an implicit `Sized` bound in `std::mem::size_of` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL error[E0277]: the size for values of type `[&U]` cannot be known at compilation time @@ -82,7 +82,7 @@ LL | mem::size_of::<[&U]>(); | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[&U]` -note: required by a bound in `std::mem::size_of` +note: required by an implicit `Sized` bound in `std::mem::size_of` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL error: aborting due to 7 previous errors diff --git a/tests/ui/unsized/unsized-bare-typaram.stderr b/tests/ui/unsized/unsized-bare-typaram.stderr index aa3f8fae72a17..4202e76b6a2ae 100644 --- a/tests/ui/unsized/unsized-bare-typaram.stderr +++ b/tests/ui/unsized/unsized-bare-typaram.stderr @@ -7,10 +7,10 @@ LL | fn foo() { bar::() } | this type parameter needs to be `Sized` | note: required by a bound in `bar` - --> $DIR/unsized-bare-typaram.rs:1:8 + --> $DIR/unsized-bare-typaram.rs:1:11 | LL | fn bar() { } - | ^ required by this bound in `bar` + | ^^^^^ required by this bound in `bar` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn foo() { bar::() } diff --git a/tests/ui/unsized/unsized-enum.stderr b/tests/ui/unsized/unsized-enum.stderr index 8c56a83a5122e..003922a149e31 100644 --- a/tests/ui/unsized/unsized-enum.stderr +++ b/tests/ui/unsized/unsized-enum.stderr @@ -6,11 +6,11 @@ LL | fn foo2() { not_sized::>() } | | | this type parameter needs to be `Sized` | -note: required by a bound in `Foo` +note: required by an implicit `Sized` bound in `Foo` --> $DIR/unsized-enum.rs:4:10 | LL | enum Foo { FooSome(U), FooNone } - | ^ required by this bound in `Foo` + | ^ required by the implicit `Sized` requirement on this bound in `Foo` help: you could relax the implicit `Sized` bound on `U` if it were used through indirection like `&U` or `Box` --> $DIR/unsized-enum.rs:4:10 | diff --git a/tests/ui/unsized/unsized-inherent-impl-self-type.stderr b/tests/ui/unsized/unsized-inherent-impl-self-type.stderr index 3e16a20d726dc..4f5e69135be99 100644 --- a/tests/ui/unsized/unsized-inherent-impl-self-type.stderr +++ b/tests/ui/unsized/unsized-inherent-impl-self-type.stderr @@ -6,11 +6,11 @@ LL | impl S5 { | | | this type parameter needs to be `Sized` | -note: required by a bound in `S5` +note: required by an implicit `Sized` bound in `S5` --> $DIR/unsized-inherent-impl-self-type.rs:5:11 | LL | struct S5(Y); - | ^ required by this bound in `S5` + | ^ required by the implicit `Sized` requirement on this bound in `S5` help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box` --> $DIR/unsized-inherent-impl-self-type.rs:5:11 | diff --git a/tests/ui/unsized/unsized-struct.stderr b/tests/ui/unsized/unsized-struct.stderr index 4e7cb09f0ccaf..92cedecd60592 100644 --- a/tests/ui/unsized/unsized-struct.stderr +++ b/tests/ui/unsized/unsized-struct.stderr @@ -6,11 +6,11 @@ LL | fn foo2() { not_sized::>() } | | | this type parameter needs to be `Sized` | -note: required by a bound in `Foo` +note: required by an implicit `Sized` bound in `Foo` --> $DIR/unsized-struct.rs:4:12 | LL | struct Foo { data: T } - | ^ required by this bound in `Foo` + | ^ required by the implicit `Sized` requirement on this bound in `Foo` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/unsized-struct.rs:4:12 | @@ -38,10 +38,10 @@ note: required because it appears within the type `Bar` LL | struct Bar { data: T } | ^^^ note: required by a bound in `is_sized` - --> $DIR/unsized-struct.rs:1:13 + --> $DIR/unsized-struct.rs:1:15 | LL | fn is_sized() { } - | ^ required by this bound in `is_sized` + | ^^^^^ required by this bound in `is_sized` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn bar2() { is_sized::>() } diff --git a/tests/ui/unsized/unsized-trait-impl-self-type.stderr b/tests/ui/unsized/unsized-trait-impl-self-type.stderr index 5bc8dc590cacb..43a3d9d00c4da 100644 --- a/tests/ui/unsized/unsized-trait-impl-self-type.stderr +++ b/tests/ui/unsized/unsized-trait-impl-self-type.stderr @@ -6,11 +6,11 @@ LL | impl T3 for S5 { | | | this type parameter needs to be `Sized` | -note: required by a bound in `S5` +note: required by an implicit `Sized` bound in `S5` --> $DIR/unsized-trait-impl-self-type.rs:8:11 | LL | struct S5(Y); - | ^ required by this bound in `S5` + | ^ required by the implicit `Sized` requirement on this bound in `S5` help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box` --> $DIR/unsized-trait-impl-self-type.rs:8:11 | diff --git a/tests/ui/unsized/unsized-trait-impl-trait-arg.stderr b/tests/ui/unsized/unsized-trait-impl-trait-arg.stderr index e9353d2bbd94a..2ce9dcd221063 100644 --- a/tests/ui/unsized/unsized-trait-impl-trait-arg.stderr +++ b/tests/ui/unsized/unsized-trait-impl-trait-arg.stderr @@ -6,11 +6,11 @@ LL | impl T2 for S4 { | | | this type parameter needs to be `Sized` | -note: required by a bound in `T2` +note: required by an implicit `Sized` bound in `T2` --> $DIR/unsized-trait-impl-trait-arg.rs:4:10 | LL | trait T2 { - | ^ required by this bound in `T2` + | ^ required by the implicit `Sized` requirement on this bound in `T2` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl T2 for S4 { diff --git a/tests/ui/unsized/unsized3.stderr b/tests/ui/unsized/unsized3.stderr index a11243980d1a3..6d17b7b9c71ff 100644 --- a/tests/ui/unsized/unsized3.stderr +++ b/tests/ui/unsized/unsized3.stderr @@ -6,11 +6,11 @@ LL | fn f1(x: &X) { LL | f2::(x); | ^ doesn't have a size known at compile-time | -note: required by a bound in `f2` +note: required by an implicit `Sized` bound in `f2` --> $DIR/unsized3.rs:10:7 | LL | fn f2(x: &X) { - | ^ required by this bound in `f2` + | ^ required by the implicit `Sized` requirement on this bound in `f2` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f1(x: &X) { @@ -29,11 +29,11 @@ LL | fn f3(x: &X) { LL | f4::(x); | ^ doesn't have a size known at compile-time | -note: required by a bound in `f4` +note: required by an implicit `Sized` bound in `f4` --> $DIR/unsized3.rs:21:7 | LL | fn f4(x: &X) { - | ^ required by this bound in `f4` + | ^ required by the implicit `Sized` requirement on this bound in `f4` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f3(x: &X) { @@ -59,11 +59,11 @@ note: required because it appears within the type `S` | LL | struct S { | ^ -note: required by a bound in `f5` +note: required by an implicit `Sized` bound in `f5` --> $DIR/unsized3.rs:24:7 | LL | fn f5(x: &Y) {} - | ^ required by this bound in `f5` + | ^ required by the implicit `Sized` requirement on this bound in `f5` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f8(x1: &S, x2: &S) { @@ -131,11 +131,11 @@ note: required because it appears within the type `S` LL | struct S { | ^ = note: required because it appears within the type `({integer}, S)` -note: required by a bound in `f5` +note: required by an implicit `Sized` bound in `f5` --> $DIR/unsized3.rs:24:7 | LL | fn f5(x: &Y) {} - | ^ required by this bound in `f5` + | ^ required by the implicit `Sized` requirement on this bound in `f5` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f10(x1: Box>) { diff --git a/tests/ui/unsized/unsized7.stderr b/tests/ui/unsized/unsized7.stderr index 2edde15965343..3580d8581360d 100644 --- a/tests/ui/unsized/unsized7.stderr +++ b/tests/ui/unsized/unsized7.stderr @@ -6,11 +6,11 @@ LL | impl T1 for S3 { | | | this type parameter needs to be `Sized` | -note: required by a bound in `T1` +note: required by an implicit `Sized` bound in `T1` --> $DIR/unsized7.rs:7:10 | LL | trait T1 { - | ^ required by this bound in `T1` + | ^ required by the implicit `Sized` requirement on this bound in `T1` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl T1 for S3 { diff --git a/tests/ui/wf/hir-wf-canonicalized.stderr b/tests/ui/wf/hir-wf-canonicalized.stderr index 21122e37da53d..2d2ad331fc692 100644 --- a/tests/ui/wf/hir-wf-canonicalized.stderr +++ b/tests/ui/wf/hir-wf-canonicalized.stderr @@ -29,11 +29,11 @@ LL | callback: Box>>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Callback, for<'b, 'c, 'd> Output = ()> + 'static)` -note: required by a bound in `Bar` +note: required by an implicit `Sized` bound in `Bar` --> $DIR/hir-wf-canonicalized.rs:9:16 | LL | struct Bar<'a, T> { - | ^ required by this bound in `Bar` + | ^ required by the implicit `Sized` requirement on this bound in `Bar` help: consider relaxing the implicit `Sized` restriction | LL | struct Bar<'a, T: ?Sized> { diff --git a/tests/ui/wf/wf-fn-where-clause.stderr b/tests/ui/wf/wf-fn-where-clause.stderr index cd6c051feedf5..d64a6eee1abe2 100644 --- a/tests/ui/wf/wf-fn-where-clause.stderr +++ b/tests/ui/wf/wf-fn-where-clause.stderr @@ -30,11 +30,11 @@ LL | fn bar() where Vec:, {} | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)` -note: required by a bound in `Vec` +note: required by an implicit `Sized` bound in `Vec` --> $DIR/wf-fn-where-clause.rs:16:12 | LL | struct Vec { - | ^ required by this bound in `Vec` + | ^ required by the implicit `Sized` requirement on this bound in `Vec` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/wf-fn-where-clause.rs:16:12 | diff --git a/tests/ui/wf/wf-impl-self-type.stderr b/tests/ui/wf/wf-impl-self-type.stderr index 86fe6df32bf21..6c3abd9f2816e 100644 --- a/tests/ui/wf/wf-impl-self-type.stderr +++ b/tests/ui/wf/wf-impl-self-type.stderr @@ -5,7 +5,7 @@ LL | impl Foo for Option<[u8]> {} | ^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Option` +note: required by an implicit `Sized` bound in `Option` --> $SRC_DIR/core/src/option.rs:LL:COL error: aborting due to 1 previous error From 95d9009f49100a6cd111557bfc16e6bc997656cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 25 Jan 2024 01:31:08 +0000 Subject: [PATCH 27/35] Change incr comp test when adding explicit `Sized` bound Given the previous change to add implicit `Sized` bounds only if there isn't already an explicit `Sized` bound, now the incr comp machinery doesn't consider adding the explicit bound as being dirty, as long as `-Zincremental-ignore-spans` is set. --- tests/incremental/hashes/trait_defs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index 49c388600de05..437b364e001ee 100644 --- a/tests/incremental/hashes/trait_defs.rs +++ b/tests/incremental/hashes/trait_defs.rs @@ -559,10 +559,10 @@ trait TraitAddBuiltinBoundToMethodTypeParameter { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5")] +#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddBuiltinBoundToMethodTypeParameter { - #[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail2")] + #[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] From 8b0ab54ffefd8855a9030f2c08463f041d0e9770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 30 Jan 2024 19:47:45 +0000 Subject: [PATCH 28/35] review comment: change wording --- .../src/traits/error_reporting/suggestions.rs | 6 +++--- tests/ui/associated-types/issue-20005.stderr | 2 +- tests/ui/dst/dst-sized-trait-param.stderr | 2 +- tests/ui/extern/extern-types-unsized.stderr | 8 ++++---- .../issue-88287.stderr | 2 +- tests/ui/impl-trait/in-trait/wf-bounds.stderr | 2 +- tests/ui/issues/issue-10412.stderr | 2 +- tests/ui/issues/issue-18919.stderr | 2 +- tests/ui/issues/issue-23281.stderr | 2 +- tests/ui/issues/issue-87199.stderr | 2 +- .../do-not-ice-on-note_and_explain.stderr | 2 +- tests/ui/methods/issues/issue-61525.stderr | 2 +- ...ject-safety-supertrait-mentions-Self.stderr | 2 +- tests/ui/str/str-mut-idx.stderr | 2 +- .../adt-param-with-implicit-sized-bound.stderr | 10 +++++----- ...-unsized-indirection-in-where-clause.stderr | 2 +- ...ultiline-trait-bound-in-where-clause.stderr | 6 +++--- tests/ui/trait-bounds/unsized-bound.stderr | 18 +++++++++--------- tests/ui/traits/issue-28576.stderr | 4 ++-- .../recursive-self-normalization-2.stderr | 4 ++-- .../recursive-self-normalization.stderr | 4 ++-- tests/ui/unsized/unsized-enum.stderr | 2 +- .../unsized-inherent-impl-self-type.stderr | 2 +- tests/ui/unsized/unsized-struct.stderr | 2 +- .../unsized-trait-impl-self-type.stderr | 2 +- .../unsized-trait-impl-trait-arg.stderr | 2 +- tests/ui/unsized/unsized3.stderr | 8 ++++---- tests/ui/unsized/unsized7.stderr | 2 +- tests/ui/wf/hir-wf-canonicalized.stderr | 2 +- tests/ui/wf/wf-fn-where-clause.stderr | 2 +- 30 files changed, 55 insertions(+), 55 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 3060f33330e51..a1e1130796b55 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3010,7 +3010,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } let mut a = "a"; - let mut this = "this"; + let mut this = "this bound"; let mut note = None; let mut help = None; if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() @@ -3036,7 +3036,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .any(|param| tcx.def_span(param.def_id) == span) { a = "an implicit `Sized`"; - this = "the implicit `Sized` requirement on this"; + this = "the implicit `Sized` requirement on this type parameter"; } if let Some(hir::Node::TraitItem(hir::TraitItem { ident, @@ -3106,7 +3106,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }; let descr = format!("required by {a} bound in `{item_name}`"); if span.is_visible(sm) { - let msg = format!("required by {this} bound in `{short_item_name}`"); + let msg = format!("required by {this} in `{short_item_name}`"); multispan.push_span_label(span, msg); err.span_note(multispan, descr); } else { diff --git a/tests/ui/associated-types/issue-20005.stderr b/tests/ui/associated-types/issue-20005.stderr index ce3f556f2d744..f2983383fa623 100644 --- a/tests/ui/associated-types/issue-20005.stderr +++ b/tests/ui/associated-types/issue-20005.stderr @@ -8,7 +8,7 @@ note: required by an implicit `Sized` bound in `From` --> $DIR/issue-20005.rs:1:12 | LL | trait From { - | ^^^ required by the implicit `Sized` requirement on this bound in `From` + | ^^^ required by the implicit `Sized` requirement on this type parameter in `From` help: consider further restricting `Self` | LL | ) -> >::Result where Dst: From, Self: Sized { diff --git a/tests/ui/dst/dst-sized-trait-param.stderr b/tests/ui/dst/dst-sized-trait-param.stderr index a3a686dced217..2ac666c8a2cc7 100644 --- a/tests/ui/dst/dst-sized-trait-param.stderr +++ b/tests/ui/dst/dst-sized-trait-param.stderr @@ -9,7 +9,7 @@ note: required by an implicit `Sized` bound in `Foo` --> $DIR/dst-sized-trait-param.rs:5:11 | LL | trait Foo : Sized { fn take(self, x: &T) { } } // Note: T is sized - | ^ required by the implicit `Sized` requirement on this bound in `Foo` + | ^ required by the implicit `Sized` requirement on this type parameter in `Foo` help: consider relaxing the implicit `Sized` restriction | LL | trait Foo : Sized { fn take(self, x: &T) { } } // Note: T is sized diff --git a/tests/ui/extern/extern-types-unsized.stderr b/tests/ui/extern/extern-types-unsized.stderr index 6592724a53e70..7428e6a60b520 100644 --- a/tests/ui/extern/extern-types-unsized.stderr +++ b/tests/ui/extern/extern-types-unsized.stderr @@ -9,7 +9,7 @@ note: required by an implicit `Sized` bound in `assert_sized` --> $DIR/extern-types-unsized.rs:19:17 | LL | fn assert_sized() {} - | ^ required by the implicit `Sized` requirement on this bound in `assert_sized` + | ^ required by the implicit `Sized` requirement on this type parameter in `assert_sized` help: consider relaxing the implicit `Sized` restriction | LL | fn assert_sized() {} @@ -31,7 +31,7 @@ note: required by an implicit `Sized` bound in `assert_sized` --> $DIR/extern-types-unsized.rs:19:17 | LL | fn assert_sized() {} - | ^ required by the implicit `Sized` requirement on this bound in `assert_sized` + | ^ required by the implicit `Sized` requirement on this type parameter in `assert_sized` help: consider relaxing the implicit `Sized` restriction | LL | fn assert_sized() {} @@ -53,7 +53,7 @@ note: required by an implicit `Sized` bound in `assert_sized` --> $DIR/extern-types-unsized.rs:19:17 | LL | fn assert_sized() {} - | ^ required by the implicit `Sized` requirement on this bound in `assert_sized` + | ^ required by the implicit `Sized` requirement on this type parameter in `assert_sized` help: consider relaxing the implicit `Sized` restriction | LL | fn assert_sized() {} @@ -75,7 +75,7 @@ note: required by an implicit `Sized` bound in `assert_sized` --> $DIR/extern-types-unsized.rs:19:17 | LL | fn assert_sized() {} - | ^ required by the implicit `Sized` requirement on this bound in `assert_sized` + | ^ required by the implicit `Sized` requirement on this type parameter in `assert_sized` help: consider relaxing the implicit `Sized` restriction | LL | fn assert_sized() {} diff --git a/tests/ui/generic-associated-types/issue-88287.stderr b/tests/ui/generic-associated-types/issue-88287.stderr index 6b26223dd5144..54ecc5cfcd810 100644 --- a/tests/ui/generic-associated-types/issue-88287.stderr +++ b/tests/ui/generic-associated-types/issue-88287.stderr @@ -11,7 +11,7 @@ note: required by an implicit `Sized` bound in ` $DIR/issue-88287.rs:24:6 | LL | impl SearchableResourceExt for T - | ^ required by the implicit `Sized` requirement on this bound in `>` + | ^ required by the implicit `Sized` requirement on this type parameter in `>` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - A: SearchableResource + ?Sized + 'f, diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.stderr index e2e06ba4e5ae8..7d42659d81edb 100644 --- a/tests/ui/impl-trait/in-trait/wf-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/wf-bounds.stderr @@ -19,7 +19,7 @@ note: required by an implicit `Sized` bound in `Wf` --> $DIR/wf-bounds.rs:7:10 | LL | trait Wf { - | ^ required by the implicit `Sized` requirement on this bound in `Wf` + | ^ required by the implicit `Sized` requirement on this type parameter in `Wf` help: consider relaxing the implicit `Sized` restriction | LL | trait Wf { diff --git a/tests/ui/issues/issue-10412.stderr b/tests/ui/issues/issue-10412.stderr index dcf7769264b22..02a26034f9aa7 100644 --- a/tests/ui/issues/issue-10412.stderr +++ b/tests/ui/issues/issue-10412.stderr @@ -62,7 +62,7 @@ note: required by an implicit `Sized` bound in `Serializable` --> $DIR/issue-10412.rs:1:27 | LL | trait Serializable<'self, T> { - | ^ required by the implicit `Sized` requirement on this bound in `Serializable` + | ^ required by the implicit `Sized` requirement on this type parameter in `Serializable` help: consider relaxing the implicit `Sized` restriction | LL | trait Serializable<'self, T: ?Sized> { diff --git a/tests/ui/issues/issue-18919.stderr b/tests/ui/issues/issue-18919.stderr index 471b5d5bdf12a..714b6d7d86be3 100644 --- a/tests/ui/issues/issue-18919.stderr +++ b/tests/ui/issues/issue-18919.stderr @@ -9,7 +9,7 @@ note: required by an implicit `Sized` bound in `Option` --> $DIR/issue-18919.rs:7:13 | LL | enum Option { - | ^ required by the implicit `Sized` requirement on this bound in `Option` + | ^ required by the implicit `Sized` requirement on this type parameter in `Option` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/issue-18919.rs:7:13 | diff --git a/tests/ui/issues/issue-23281.stderr b/tests/ui/issues/issue-23281.stderr index 4c25d1efedd6a..ee079f2deeca3 100644 --- a/tests/ui/issues/issue-23281.stderr +++ b/tests/ui/issues/issue-23281.stderr @@ -9,7 +9,7 @@ note: required by an implicit `Sized` bound in `Vec` --> $DIR/issue-23281.rs:8:12 | LL | struct Vec { - | ^ required by the implicit `Sized` requirement on this bound in `Vec` + | ^ required by the implicit `Sized` requirement on this type parameter in `Vec` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/issue-23281.rs:8:12 | diff --git a/tests/ui/issues/issue-87199.stderr b/tests/ui/issues/issue-87199.stderr index 6c4fbddb04924..34433eef5c70b 100644 --- a/tests/ui/issues/issue-87199.stderr +++ b/tests/ui/issues/issue-87199.stderr @@ -27,7 +27,7 @@ note: required by an implicit `Sized` bound in `ref_arg` --> $DIR/issue-87199.rs:10:12 | LL | fn ref_arg(_: &T) {} - | ^ required by the implicit `Sized` requirement on this bound in `ref_arg` + | ^ required by the implicit `Sized` requirement on this type parameter in `ref_arg` help: consider relaxing the implicit `Sized` restriction | LL | fn ref_arg(_: &T) {} diff --git a/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr b/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr index 47c01b9e805d8..41d0f17366b1e 100644 --- a/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr +++ b/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr @@ -64,7 +64,7 @@ note: required by an implicit `Sized` bound in `A` --> $DIR/do-not-ice-on-note_and_explain.rs:1:10 | LL | struct A(B); - | ^ required by the implicit `Sized` requirement on this bound in `A` + | ^ required by the implicit `Sized` requirement on this type parameter in `A` help: you could relax the implicit `Sized` bound on `B` if it were used through indirection like `&B` or `Box` --> $DIR/do-not-ice-on-note_and_explain.rs:1:10 | diff --git a/tests/ui/methods/issues/issue-61525.stderr b/tests/ui/methods/issues/issue-61525.stderr index 777d0b4f3d125..35001ae22a6c7 100644 --- a/tests/ui/methods/issues/issue-61525.stderr +++ b/tests/ui/methods/issues/issue-61525.stderr @@ -11,7 +11,7 @@ note: required by an implicit `Sized` bound in `Example::query` --> $DIR/issue-61525.rs:2:14 | LL | fn query(self, q: Q); - | ^ required by the implicit `Sized` requirement on this bound in `Example::query` + | ^ required by the implicit `Sized` requirement on this type parameter in `Example::query` help: consider relaxing the implicit `Sized` restriction | LL | fn query(self, q: Q); diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr index 2380cba89486f..e7fcdbd0c9c53 100644 --- a/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr +++ b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr @@ -26,7 +26,7 @@ note: required by an implicit `Sized` bound in `Bar` --> $DIR/object-safety-supertrait-mentions-Self.rs:4:11 | LL | trait Bar { - | ^ required by the implicit `Sized` requirement on this bound in `Bar` + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` help: consider further restricting `Self` | LL | trait Baz : Bar + Sized { diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index 5a2664f4522e8..679f783126ff4 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -9,7 +9,7 @@ note: required by an implicit `Sized` bound in `bot` --> $DIR/str-mut-idx.rs:1:8 | LL | fn bot() -> T { loop {} } - | ^ required by the implicit `Sized` requirement on this bound in `bot` + | ^ required by the implicit `Sized` requirement on this type parameter in `bot` help: consider relaxing the implicit `Sized` restriction | LL | fn bot() -> T { loop {} } diff --git a/tests/ui/suggestions/adt-param-with-implicit-sized-bound.stderr b/tests/ui/suggestions/adt-param-with-implicit-sized-bound.stderr index 705f078c367d0..6da6f8e23b4f4 100644 --- a/tests/ui/suggestions/adt-param-with-implicit-sized-bound.stderr +++ b/tests/ui/suggestions/adt-param-with-implicit-sized-bound.stderr @@ -10,7 +10,7 @@ note: required by an implicit `Sized` bound in `X` --> $DIR/adt-param-with-implicit-sized-bound.rs:18:10 | LL | struct X(T); - | ^ required by the implicit `Sized` requirement on this bound in `X` + | ^ required by the implicit `Sized` requirement on this type parameter in `X` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/adt-param-with-implicit-sized-bound.rs:18:10 | @@ -34,7 +34,7 @@ note: required by an implicit `Sized` bound in `Struct1` --> $DIR/adt-param-with-implicit-sized-bound.rs:8:16 | LL | struct Struct1{ - | ^ required by the implicit `Sized` requirement on this bound in `Struct1` + | ^ required by the implicit `Sized` requirement on this type parameter in `Struct1` help: consider further restricting `Self` | LL | fn func1() -> Struct1 where Self: Sized; @@ -54,7 +54,7 @@ note: required by an implicit `Sized` bound in `Struct2` --> $DIR/adt-param-with-implicit-sized-bound.rs:11:20 | LL | struct Struct2<'a, T>{ - | ^ required by the implicit `Sized` requirement on this bound in `Struct2` + | ^ required by the implicit `Sized` requirement on this type parameter in `Struct2` help: consider further restricting `Self` | LL | fn func2<'a>() -> Struct2<'a, Self> where Self: Sized; @@ -74,7 +74,7 @@ note: required by an implicit `Sized` bound in `Struct3` --> $DIR/adt-param-with-implicit-sized-bound.rs:14:16 | LL | struct Struct3{ - | ^ required by the implicit `Sized` requirement on this bound in `Struct3` + | ^ required by the implicit `Sized` requirement on this type parameter in `Struct3` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/adt-param-with-implicit-sized-bound.rs:14:16 | @@ -97,7 +97,7 @@ note: required by an implicit `Sized` bound in `Struct4` --> $DIR/adt-param-with-implicit-sized-bound.rs:20:16 | LL | struct Struct4{ - | ^ required by the implicit `Sized` requirement on this bound in `Struct4` + | ^ required by the implicit `Sized` requirement on this type parameter in `Struct4` help: consider further restricting `Self` | LL | fn func4() -> Struct4 where Self: Sized; diff --git a/tests/ui/suggestions/issue-85943-no-suggest-unsized-indirection-in-where-clause.stderr b/tests/ui/suggestions/issue-85943-no-suggest-unsized-indirection-in-where-clause.stderr index e2f1532cc4eaf..7dcb2deb06a04 100644 --- a/tests/ui/suggestions/issue-85943-no-suggest-unsized-indirection-in-where-clause.stderr +++ b/tests/ui/suggestions/issue-85943-no-suggest-unsized-indirection-in-where-clause.stderr @@ -9,7 +9,7 @@ note: required by an implicit `Sized` bound in `A` --> $DIR/issue-85943-no-suggest-unsized-indirection-in-where-clause.rs:4:10 | LL | struct A(T) where T: Send; - | ^ required by the implicit `Sized` requirement on this bound in `A` + | ^ required by the implicit `Sized` requirement on this type parameter in `A` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/issue-85943-no-suggest-unsized-indirection-in-where-clause.rs:4:10 | diff --git a/tests/ui/suggestions/removal-of-multiline-trait-bound-in-where-clause.stderr b/tests/ui/suggestions/removal-of-multiline-trait-bound-in-where-clause.stderr index 7d20120654af3..dcab4d7c4fcb3 100644 --- a/tests/ui/suggestions/removal-of-multiline-trait-bound-in-where-clause.stderr +++ b/tests/ui/suggestions/removal-of-multiline-trait-bound-in-where-clause.stderr @@ -10,7 +10,7 @@ note: required by an implicit `Sized` bound in `Wrapper` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | LL | struct Wrapper(T); - | ^ required by the implicit `Sized` requirement on this bound in `Wrapper` + | ^ required by the implicit `Sized` requirement on this type parameter in `Wrapper` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | @@ -39,7 +39,7 @@ note: required by an implicit `Sized` bound in `Wrapper` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | LL | struct Wrapper(T); - | ^ required by the implicit `Sized` requirement on this bound in `Wrapper` + | ^ required by the implicit `Sized` requirement on this type parameter in `Wrapper` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | @@ -64,7 +64,7 @@ note: required by an implicit `Sized` bound in `Wrapper` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | LL | struct Wrapper(T); - | ^ required by the implicit `Sized` requirement on this bound in `Wrapper` + | ^ required by the implicit `Sized` requirement on this type parameter in `Wrapper` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16 | diff --git a/tests/ui/trait-bounds/unsized-bound.stderr b/tests/ui/trait-bounds/unsized-bound.stderr index 87a43a6fddab0..c8049ebee1173 100644 --- a/tests/ui/trait-bounds/unsized-bound.stderr +++ b/tests/ui/trait-bounds/unsized-bound.stderr @@ -11,7 +11,7 @@ note: required by an implicit `Sized` bound in `Trait` --> $DIR/unsized-bound.rs:1:13 | LL | trait Trait {} - | ^ required by the implicit `Sized` requirement on this bound in `Trait` + | ^ required by the implicit `Sized` requirement on this type parameter in `Trait` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} @@ -50,7 +50,7 @@ note: required by an implicit `Sized` bound in `Trait` --> $DIR/unsized-bound.rs:1:13 | LL | trait Trait {} - | ^ required by the implicit `Sized` requirement on this bound in `Trait` + | ^ required by the implicit `Sized` requirement on this type parameter in `Trait` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} @@ -100,7 +100,7 @@ note: required by an implicit `Sized` bound in `Trait2` --> $DIR/unsized-bound.rs:9:14 | LL | trait Trait2 {} - | ^ required by the implicit `Sized` requirement on this bound in `Trait2` + | ^ required by the implicit `Sized` requirement on this type parameter in `Trait2` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait2<(A, B)> for (A, B) {} @@ -138,7 +138,7 @@ note: required by an implicit `Sized` bound in `Trait3` --> $DIR/unsized-bound.rs:13:14 | LL | trait Trait3 {} - | ^ required by the implicit `Sized` requirement on this bound in `Trait3` + | ^ required by the implicit `Sized` requirement on this type parameter in `Trait3` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait3 for A where A: ?Sized {} @@ -161,7 +161,7 @@ note: required by an implicit `Sized` bound in `Trait4` --> $DIR/unsized-bound.rs:16:14 | LL | trait Trait4 {} - | ^ required by the implicit `Sized` requirement on this bound in `Trait4` + | ^ required by the implicit `Sized` requirement on this type parameter in `Trait4` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait4 for A {} @@ -184,7 +184,7 @@ note: required by an implicit `Sized` bound in `Trait5` --> $DIR/unsized-bound.rs:19:14 | LL | trait Trait5 {} - | ^ required by the implicit `Sized` requirement on this bound in `Trait5` + | ^ required by the implicit `Sized` requirement on this type parameter in `Trait5` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait5 for X where X: ?Sized {} @@ -207,7 +207,7 @@ note: required by an implicit `Sized` bound in `Trait6` --> $DIR/unsized-bound.rs:22:14 | LL | trait Trait6 {} - | ^ required by the implicit `Sized` requirement on this bound in `Trait6` + | ^ required by the implicit `Sized` requirement on this type parameter in `Trait6` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait6 for X {} @@ -230,7 +230,7 @@ note: required by an implicit `Sized` bound in `Trait7` --> $DIR/unsized-bound.rs:25:17 | LL | trait Trait7 {} - | ^ required by the implicit `Sized` requirement on this bound in `Trait7` + | ^ required by the implicit `Sized` requirement on this type parameter in `Trait7` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait7 for X where Y: ?Sized {} @@ -253,7 +253,7 @@ note: required by an implicit `Sized` bound in `Trait8` --> $DIR/unsized-bound.rs:28:17 | LL | trait Trait8 {} - | ^ required by the implicit `Sized` requirement on this bound in `Trait8` + | ^ required by the implicit `Sized` requirement on this type parameter in `Trait8` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl Trait8 for X {} diff --git a/tests/ui/traits/issue-28576.stderr b/tests/ui/traits/issue-28576.stderr index dc08f9f6ccd4c..adba5830b10e1 100644 --- a/tests/ui/traits/issue-28576.stderr +++ b/tests/ui/traits/issue-28576.stderr @@ -29,7 +29,7 @@ note: required by an implicit `Sized` bound in `Foo` --> $DIR/issue-28576.rs:1:15 | LL | pub trait Foo { - | ^^^^^^^^ required by the implicit `Sized` requirement on this bound in `Foo` + | ^^^^^^^^ required by the implicit `Sized` requirement on this type parameter in `Foo` help: consider further restricting `Self` | LL | pub trait Bar: Foo + Sized { @@ -49,7 +49,7 @@ note: required by an implicit `Sized` bound in `Foo` --> $DIR/issue-28576.rs:1:15 | LL | pub trait Foo { - | ^^^^^^^^ required by the implicit `Sized` requirement on this bound in `Foo` + | ^^^^^^^^ required by the implicit `Sized` requirement on this type parameter in `Foo` help: consider further restricting `Self` | LL | ) where Self: Sized; diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr index ed87404d57395..09622bb9b6c28 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr @@ -26,11 +26,11 @@ LL | needs_bar::(); | ^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`) -note: required by a bound in `needs_bar` +note: required by an implicit `Sized` bound in `needs_bar` --> $DIR/recursive-self-normalization-2.rs:12:14 | LL | fn needs_bar() {} - | ^ required by this bound in `needs_bar` + | ^ required by the implicit `Sized` requirement on this type parameter in `needs_bar` help: consider relaxing the implicit `Sized` restriction | LL | fn needs_bar() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr index e4ef2f60740f4..7c058909df7c5 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr @@ -26,11 +26,11 @@ LL | needs_bar::(); | ^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`) -note: required by a bound in `needs_bar` +note: required by an implicit `Sized` bound in `needs_bar` --> $DIR/recursive-self-normalization.rs:8:14 | LL | fn needs_bar() {} - | ^ required by this bound in `needs_bar` + | ^ required by the implicit `Sized` requirement on this type parameter in `needs_bar` help: consider relaxing the implicit `Sized` restriction | LL | fn needs_bar() {} diff --git a/tests/ui/unsized/unsized-enum.stderr b/tests/ui/unsized/unsized-enum.stderr index 003922a149e31..5a30d7fab65a7 100644 --- a/tests/ui/unsized/unsized-enum.stderr +++ b/tests/ui/unsized/unsized-enum.stderr @@ -10,7 +10,7 @@ note: required by an implicit `Sized` bound in `Foo` --> $DIR/unsized-enum.rs:4:10 | LL | enum Foo { FooSome(U), FooNone } - | ^ required by the implicit `Sized` requirement on this bound in `Foo` + | ^ required by the implicit `Sized` requirement on this type parameter in `Foo` help: you could relax the implicit `Sized` bound on `U` if it were used through indirection like `&U` or `Box` --> $DIR/unsized-enum.rs:4:10 | diff --git a/tests/ui/unsized/unsized-inherent-impl-self-type.stderr b/tests/ui/unsized/unsized-inherent-impl-self-type.stderr index 4f5e69135be99..5a379f4065aa7 100644 --- a/tests/ui/unsized/unsized-inherent-impl-self-type.stderr +++ b/tests/ui/unsized/unsized-inherent-impl-self-type.stderr @@ -10,7 +10,7 @@ note: required by an implicit `Sized` bound in `S5` --> $DIR/unsized-inherent-impl-self-type.rs:5:11 | LL | struct S5(Y); - | ^ required by the implicit `Sized` requirement on this bound in `S5` + | ^ required by the implicit `Sized` requirement on this type parameter in `S5` help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box` --> $DIR/unsized-inherent-impl-self-type.rs:5:11 | diff --git a/tests/ui/unsized/unsized-struct.stderr b/tests/ui/unsized/unsized-struct.stderr index 92cedecd60592..06c4ffb7773c6 100644 --- a/tests/ui/unsized/unsized-struct.stderr +++ b/tests/ui/unsized/unsized-struct.stderr @@ -10,7 +10,7 @@ note: required by an implicit `Sized` bound in `Foo` --> $DIR/unsized-struct.rs:4:12 | LL | struct Foo { data: T } - | ^ required by the implicit `Sized` requirement on this bound in `Foo` + | ^ required by the implicit `Sized` requirement on this type parameter in `Foo` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/unsized-struct.rs:4:12 | diff --git a/tests/ui/unsized/unsized-trait-impl-self-type.stderr b/tests/ui/unsized/unsized-trait-impl-self-type.stderr index 43a3d9d00c4da..3b684193b4aca 100644 --- a/tests/ui/unsized/unsized-trait-impl-self-type.stderr +++ b/tests/ui/unsized/unsized-trait-impl-self-type.stderr @@ -10,7 +10,7 @@ note: required by an implicit `Sized` bound in `S5` --> $DIR/unsized-trait-impl-self-type.rs:8:11 | LL | struct S5(Y); - | ^ required by the implicit `Sized` requirement on this bound in `S5` + | ^ required by the implicit `Sized` requirement on this type parameter in `S5` help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box` --> $DIR/unsized-trait-impl-self-type.rs:8:11 | diff --git a/tests/ui/unsized/unsized-trait-impl-trait-arg.stderr b/tests/ui/unsized/unsized-trait-impl-trait-arg.stderr index 2ce9dcd221063..79fc9567dae6f 100644 --- a/tests/ui/unsized/unsized-trait-impl-trait-arg.stderr +++ b/tests/ui/unsized/unsized-trait-impl-trait-arg.stderr @@ -10,7 +10,7 @@ note: required by an implicit `Sized` bound in `T2` --> $DIR/unsized-trait-impl-trait-arg.rs:4:10 | LL | trait T2 { - | ^ required by the implicit `Sized` requirement on this bound in `T2` + | ^ required by the implicit `Sized` requirement on this type parameter in `T2` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl T2 for S4 { diff --git a/tests/ui/unsized/unsized3.stderr b/tests/ui/unsized/unsized3.stderr index 6d17b7b9c71ff..c7a145b1c5171 100644 --- a/tests/ui/unsized/unsized3.stderr +++ b/tests/ui/unsized/unsized3.stderr @@ -10,7 +10,7 @@ note: required by an implicit `Sized` bound in `f2` --> $DIR/unsized3.rs:10:7 | LL | fn f2(x: &X) { - | ^ required by the implicit `Sized` requirement on this bound in `f2` + | ^ required by the implicit `Sized` requirement on this type parameter in `f2` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f1(x: &X) { @@ -33,7 +33,7 @@ note: required by an implicit `Sized` bound in `f4` --> $DIR/unsized3.rs:21:7 | LL | fn f4(x: &X) { - | ^ required by the implicit `Sized` requirement on this bound in `f4` + | ^ required by the implicit `Sized` requirement on this type parameter in `f4` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f3(x: &X) { @@ -63,7 +63,7 @@ note: required by an implicit `Sized` bound in `f5` --> $DIR/unsized3.rs:24:7 | LL | fn f5(x: &Y) {} - | ^ required by the implicit `Sized` requirement on this bound in `f5` + | ^ required by the implicit `Sized` requirement on this type parameter in `f5` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f8(x1: &S, x2: &S) { @@ -135,7 +135,7 @@ note: required by an implicit `Sized` bound in `f5` --> $DIR/unsized3.rs:24:7 | LL | fn f5(x: &Y) {} - | ^ required by the implicit `Sized` requirement on this bound in `f5` + | ^ required by the implicit `Sized` requirement on this type parameter in `f5` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f10(x1: Box>) { diff --git a/tests/ui/unsized/unsized7.stderr b/tests/ui/unsized/unsized7.stderr index 3580d8581360d..6e9c052a07022 100644 --- a/tests/ui/unsized/unsized7.stderr +++ b/tests/ui/unsized/unsized7.stderr @@ -10,7 +10,7 @@ note: required by an implicit `Sized` bound in `T1` --> $DIR/unsized7.rs:7:10 | LL | trait T1 { - | ^ required by the implicit `Sized` requirement on this bound in `T1` + | ^ required by the implicit `Sized` requirement on this type parameter in `T1` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - impl T1 for S3 { diff --git a/tests/ui/wf/hir-wf-canonicalized.stderr b/tests/ui/wf/hir-wf-canonicalized.stderr index 2d2ad331fc692..4dca1f65232e2 100644 --- a/tests/ui/wf/hir-wf-canonicalized.stderr +++ b/tests/ui/wf/hir-wf-canonicalized.stderr @@ -33,7 +33,7 @@ note: required by an implicit `Sized` bound in `Bar` --> $DIR/hir-wf-canonicalized.rs:9:16 | LL | struct Bar<'a, T> { - | ^ required by the implicit `Sized` requirement on this bound in `Bar` + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` help: consider relaxing the implicit `Sized` restriction | LL | struct Bar<'a, T: ?Sized> { diff --git a/tests/ui/wf/wf-fn-where-clause.stderr b/tests/ui/wf/wf-fn-where-clause.stderr index d64a6eee1abe2..40f2f45263930 100644 --- a/tests/ui/wf/wf-fn-where-clause.stderr +++ b/tests/ui/wf/wf-fn-where-clause.stderr @@ -34,7 +34,7 @@ note: required by an implicit `Sized` bound in `Vec` --> $DIR/wf-fn-where-clause.rs:16:12 | LL | struct Vec { - | ^ required by the implicit `Sized` requirement on this bound in `Vec` + | ^ required by the implicit `Sized` requirement on this type parameter in `Vec` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/wf-fn-where-clause.rs:16:12 | From 4feec41e0589e53a429de261c534909703185279 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 1 Feb 2024 10:27:54 +0000 Subject: [PATCH 29/35] `#![feature(inline_const_pat)]` is no longer incomplete --- compiler/rustc_feature/src/unstable.rs | 2 +- .../invalid-inline-const-in-match-arm.rs | 1 - .../invalid-inline-const-in-match-arm.stderr | 2 +- .../range_pat_interactions0.rs | 1 - .../inline-const/const-match-pat-generic.rs | 1 - .../const-match-pat-generic.stderr | 4 ++-- .../inline-const/const-match-pat-inference.rs | 1 - .../const-match-pat-lifetime-err.rs | 1 - .../const-match-pat-lifetime-err.stderr | 4 ++-- .../inline-const/const-match-pat-lifetime.rs | 1 - .../ui/inline-const/const-match-pat-range.rs | 1 - tests/ui/inline-const/const-match-pat.rs | 1 - tests/ui/inline-const/pat-match-fndef.rs | 1 - tests/ui/inline-const/pat-match-fndef.stderr | 13 ++--------- tests/ui/inline-const/pat-unsafe-err.rs | 1 - tests/ui/inline-const/pat-unsafe-err.stderr | 4 ++-- tests/ui/inline-const/pat-unsafe.rs | 1 - tests/ui/inline-const/pat-unsafe.stderr | 6 ++--- tests/ui/lint/dead-code/anon-const-in-pat.rs | 1 - tests/ui/match/issue-112438.rs | 1 - tests/ui/match/validate-range-endpoints.rs | 1 - .../ui/match/validate-range-endpoints.stderr | 22 +++++++++---------- .../ui/pattern/non-structural-match-types.rs | 1 - .../pattern/non-structural-match-types.stderr | 8 +++---- .../unsafe/const_pat_in_layout_restricted.rs | 1 - 25 files changed, 28 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 643185ba20a7c..d00621d8254c3 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -496,7 +496,7 @@ declare_features! ( /// Allow anonymous constants from an inline `const` block (unstable, inline_const, "1.49.0", Some(76001)), /// Allow anonymous constants from an inline `const` block in pattern position - (incomplete, inline_const_pat, "1.58.0", Some(76001)), + (unstable, inline_const_pat, "1.58.0", Some(76001)), /// Allows using `pointer` and `reference` in intra-doc links (unstable, intra_doc_pointers, "1.51.0", Some(80896)), // Allows setting the threshold for the `large_assignments` lint. diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.rs b/tests/ui/consts/invalid-inline-const-in-match-arm.rs index 4d2d8fb1303ce..0654fd82fbc59 100644 --- a/tests/ui/consts/invalid-inline-const-in-match-arm.rs +++ b/tests/ui/consts/invalid-inline-const-in-match-arm.rs @@ -1,4 +1,3 @@ -#![allow(incomplete_features)] #![feature(inline_const_pat)] fn main() { diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr index db7db4b613181..a88c16158f324 100644 --- a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr +++ b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const closure in constants - --> $DIR/invalid-inline-const-in-match-arm.rs:6:17 + --> $DIR/invalid-inline-const-in-match-arm.rs:5:17 | LL | const { (|| {})() } => {} | ^^^^^^^^^ diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions0.rs b/tests/ui/half-open-range-patterns/range_pat_interactions0.rs index acb7feac132f4..e6d5e64a15b7a 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions0.rs +++ b/tests/ui/half-open-range-patterns/range_pat_interactions0.rs @@ -1,5 +1,4 @@ // run-pass -#![allow(incomplete_features)] #![feature(exclusive_range_pattern)] #![feature(inline_const_pat)] diff --git a/tests/ui/inline-const/const-match-pat-generic.rs b/tests/ui/inline-const/const-match-pat-generic.rs index 46e501abf6c2e..9d76fc2ad65bc 100644 --- a/tests/ui/inline-const/const-match-pat-generic.rs +++ b/tests/ui/inline-const/const-match-pat-generic.rs @@ -1,4 +1,3 @@ -#![allow(incomplete_features)] #![feature(inline_const_pat)] // rust-lang/rust#82518: ICE with inline-const in match referencing const-generic parameter diff --git a/tests/ui/inline-const/const-match-pat-generic.stderr b/tests/ui/inline-const/const-match-pat-generic.stderr index 4ffbde4101d72..15c3a876afcf7 100644 --- a/tests/ui/inline-const/const-match-pat-generic.stderr +++ b/tests/ui/inline-const/const-match-pat-generic.stderr @@ -1,11 +1,11 @@ error: constant pattern depends on a generic parameter - --> $DIR/const-match-pat-generic.rs:8:9 + --> $DIR/const-match-pat-generic.rs:7:9 | LL | const { V } => {}, | ^^^^^^^^^^^ error: constant pattern depends on a generic parameter - --> $DIR/const-match-pat-generic.rs:20:9 + --> $DIR/const-match-pat-generic.rs:19:9 | LL | const { f(V) } => {}, | ^^^^^^^^^^^^^^ diff --git a/tests/ui/inline-const/const-match-pat-inference.rs b/tests/ui/inline-const/const-match-pat-inference.rs index d83ae6e983486..c595824833f5f 100644 --- a/tests/ui/inline-const/const-match-pat-inference.rs +++ b/tests/ui/inline-const/const-match-pat-inference.rs @@ -1,7 +1,6 @@ // check-pass #![feature(inline_const_pat)] -#![allow(incomplete_features)] fn main() { match 1u64 { diff --git a/tests/ui/inline-const/const-match-pat-lifetime-err.rs b/tests/ui/inline-const/const-match-pat-lifetime-err.rs index ce91e5233bccd..ff0a9dbf110c4 100644 --- a/tests/ui/inline-const/const-match-pat-lifetime-err.rs +++ b/tests/ui/inline-const/const-match-pat-lifetime-err.rs @@ -1,4 +1,3 @@ -#![allow(incomplete_features)] #![feature(const_mut_refs)] #![feature(inline_const_pat)] diff --git a/tests/ui/inline-const/const-match-pat-lifetime-err.stderr b/tests/ui/inline-const/const-match-pat-lifetime-err.stderr index c5760f1027ef2..98ce6cfae7b38 100644 --- a/tests/ui/inline-const/const-match-pat-lifetime-err.stderr +++ b/tests/ui/inline-const/const-match-pat-lifetime-err.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/const-match-pat-lifetime-err.rs:29:29 + --> $DIR/const-match-pat-lifetime-err.rs:28:29 | LL | fn match_invariant_ref<'a>() { | -- lifetime `'a` defined here @@ -15,7 +15,7 @@ LL | } | - `y` dropped here while still borrowed error: lifetime may not live long enough - --> $DIR/const-match-pat-lifetime-err.rs:39:12 + --> $DIR/const-match-pat-lifetime-err.rs:38:12 | LL | fn match_covariant_ref<'a>() { | -- lifetime `'a` defined here diff --git a/tests/ui/inline-const/const-match-pat-lifetime.rs b/tests/ui/inline-const/const-match-pat-lifetime.rs index 6d943bbcc0160..595741b101e93 100644 --- a/tests/ui/inline-const/const-match-pat-lifetime.rs +++ b/tests/ui/inline-const/const-match-pat-lifetime.rs @@ -1,6 +1,5 @@ // run-pass -#![allow(incomplete_features)] #![feature(const_mut_refs)] #![feature(inline_const)] #![feature(inline_const_pat)] diff --git a/tests/ui/inline-const/const-match-pat-range.rs b/tests/ui/inline-const/const-match-pat-range.rs index 73d6334c36f8e..0f9372c537f89 100644 --- a/tests/ui/inline-const/const-match-pat-range.rs +++ b/tests/ui/inline-const/const-match-pat-range.rs @@ -1,6 +1,5 @@ // build-pass -#![allow(incomplete_features)] #![feature(inline_const_pat, exclusive_range_pattern)] fn main() { diff --git a/tests/ui/inline-const/const-match-pat.rs b/tests/ui/inline-const/const-match-pat.rs index 2f55e16b35cd9..fc4d37714585e 100644 --- a/tests/ui/inline-const/const-match-pat.rs +++ b/tests/ui/inline-const/const-match-pat.rs @@ -1,6 +1,5 @@ // run-pass -#![allow(incomplete_features)] #![feature(inline_const_pat)] const MMIO_BIT1: u8 = 4; const MMIO_BIT2: u8 = 5; diff --git a/tests/ui/inline-const/pat-match-fndef.rs b/tests/ui/inline-const/pat-match-fndef.rs index fbd4dc66c3a05..013a4a6756102 100644 --- a/tests/ui/inline-const/pat-match-fndef.rs +++ b/tests/ui/inline-const/pat-match-fndef.rs @@ -1,5 +1,4 @@ #![feature(inline_const_pat)] -//~^ WARN the feature `inline_const_pat` is incomplete fn uwu() {} diff --git a/tests/ui/inline-const/pat-match-fndef.stderr b/tests/ui/inline-const/pat-match-fndef.stderr index 02c4a60b68f20..b189ec51ade38 100644 --- a/tests/ui/inline-const/pat-match-fndef.stderr +++ b/tests/ui/inline-const/pat-match-fndef.stderr @@ -1,17 +1,8 @@ -warning: the feature `inline_const_pat` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/pat-match-fndef.rs:1:12 - | -LL | #![feature(inline_const_pat)] - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #76001 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `fn() {uwu}` cannot be used in patterns - --> $DIR/pat-match-fndef.rs:9:9 + --> $DIR/pat-match-fndef.rs:8:9 | LL | const { uwu } => {} | ^^^^^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/inline-const/pat-unsafe-err.rs b/tests/ui/inline-const/pat-unsafe-err.rs index 7680c82efb5c5..b906def702950 100644 --- a/tests/ui/inline-const/pat-unsafe-err.rs +++ b/tests/ui/inline-const/pat-unsafe-err.rs @@ -1,4 +1,3 @@ -#![allow(incomplete_features)] #![feature(inline_const_pat)] const unsafe fn require_unsafe() -> usize { diff --git a/tests/ui/inline-const/pat-unsafe-err.stderr b/tests/ui/inline-const/pat-unsafe-err.stderr index 9b995d6ccf27e..786c7f31ccce1 100644 --- a/tests/ui/inline-const/pat-unsafe-err.stderr +++ b/tests/ui/inline-const/pat-unsafe-err.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block - --> $DIR/pat-unsafe-err.rs:11:13 + --> $DIR/pat-unsafe-err.rs:10:13 | LL | require_unsafe(); | ^^^^^^^^^^^^^^^^ call to unsafe function @@ -7,7 +7,7 @@ LL | require_unsafe(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block - --> $DIR/pat-unsafe-err.rs:18:13 + --> $DIR/pat-unsafe-err.rs:17:13 | LL | require_unsafe() | ^^^^^^^^^^^^^^^^ call to unsafe function diff --git a/tests/ui/inline-const/pat-unsafe.rs b/tests/ui/inline-const/pat-unsafe.rs index f7073ef40eb09..5a90920ef3cff 100644 --- a/tests/ui/inline-const/pat-unsafe.rs +++ b/tests/ui/inline-const/pat-unsafe.rs @@ -1,6 +1,5 @@ // check-pass -#![allow(incomplete_features)] #![warn(unused_unsafe)] #![feature(inline_const_pat)] diff --git a/tests/ui/inline-const/pat-unsafe.stderr b/tests/ui/inline-const/pat-unsafe.stderr index 84dc10c490258..59460271ac010 100644 --- a/tests/ui/inline-const/pat-unsafe.stderr +++ b/tests/ui/inline-const/pat-unsafe.stderr @@ -1,17 +1,17 @@ warning: unnecessary `unsafe` block - --> $DIR/pat-unsafe.rs:16:17 + --> $DIR/pat-unsafe.rs:15:17 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here - --> $DIR/pat-unsafe.rs:4:9 + --> $DIR/pat-unsafe.rs:3:9 | LL | #![warn(unused_unsafe)] | ^^^^^^^^^^^^^ warning: unnecessary `unsafe` block - --> $DIR/pat-unsafe.rs:23:17 + --> $DIR/pat-unsafe.rs:22:17 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block diff --git a/tests/ui/lint/dead-code/anon-const-in-pat.rs b/tests/ui/lint/dead-code/anon-const-in-pat.rs index d3e39c0de69c8..4d7fdddf246ed 100644 --- a/tests/ui/lint/dead-code/anon-const-in-pat.rs +++ b/tests/ui/lint/dead-code/anon-const-in-pat.rs @@ -1,6 +1,5 @@ // check-pass #![feature(inline_const_pat)] -#![allow(incomplete_features)] #![deny(dead_code)] const fn one() -> i32 { diff --git a/tests/ui/match/issue-112438.rs b/tests/ui/match/issue-112438.rs index 15f380f7fb471..46c69d5ba9c77 100644 --- a/tests/ui/match/issue-112438.rs +++ b/tests/ui/match/issue-112438.rs @@ -1,7 +1,6 @@ // run-pass #![feature(inline_const_pat)] #![allow(dead_code)] -#![allow(incomplete_features)] fn foo() { match 0 { const { 1 << 5 } | _ => {} diff --git a/tests/ui/match/validate-range-endpoints.rs b/tests/ui/match/validate-range-endpoints.rs index 1d1737f8b82f4..31d5bc3b65d50 100644 --- a/tests/ui/match/validate-range-endpoints.rs +++ b/tests/ui/match/validate-range-endpoints.rs @@ -1,6 +1,5 @@ #![feature(exclusive_range_pattern)] #![feature(inline_const_pat)] -#![allow(incomplete_features)] #![allow(overlapping_range_endpoints)] fn main() { diff --git a/tests/ui/match/validate-range-endpoints.stderr b/tests/ui/match/validate-range-endpoints.stderr index 0813fccff5187..b3b4066cd9158 100644 --- a/tests/ui/match/validate-range-endpoints.stderr +++ b/tests/ui/match/validate-range-endpoints.stderr @@ -1,59 +1,59 @@ error: literal out of range for `u8` - --> $DIR/validate-range-endpoints.rs:9:12 + --> $DIR/validate-range-endpoints.rs:8:12 | LL | 1..257 => {} | ^^^ this value does not fit into the type `u8` whose range is `0..=255` error: literal out of range for `u8` - --> $DIR/validate-range-endpoints.rs:11:13 + --> $DIR/validate-range-endpoints.rs:10:13 | LL | 1..=256 => {} | ^^^ this value does not fit into the type `u8` whose range is `0..=255` error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/validate-range-endpoints.rs:20:9 + --> $DIR/validate-range-endpoints.rs:19:9 | LL | 1..=TOO_BIG => {} | ^^^^^^^^^^^ lower bound larger than upper bound error[E0030]: lower range bound must be less than or equal to upper - --> $DIR/validate-range-endpoints.rs:22:9 + --> $DIR/validate-range-endpoints.rs:21:9 | LL | 1..=const { 256 } => {} | ^^^^^^^^^^^^^^^^^ lower bound larger than upper bound error: literal out of range for `u64` - --> $DIR/validate-range-endpoints.rs:28:32 + --> $DIR/validate-range-endpoints.rs:27:32 | LL | 10000000000000000000..=99999999999999999999 => {} | ^^^^^^^^^^^^^^^^^^^^ this value does not fit into the type `u64` whose range is `0..=18446744073709551615` error: literal out of range for `i8` - --> $DIR/validate-range-endpoints.rs:34:12 + --> $DIR/validate-range-endpoints.rs:33:12 | LL | 0..129 => {} | ^^^ this value does not fit into the type `i8` whose range is `-128..=127` error: literal out of range for `i8` - --> $DIR/validate-range-endpoints.rs:36:13 + --> $DIR/validate-range-endpoints.rs:35:13 | LL | 0..=128 => {} | ^^^ this value does not fit into the type `i8` whose range is `-128..=127` error: literal out of range for `i8` - --> $DIR/validate-range-endpoints.rs:38:9 + --> $DIR/validate-range-endpoints.rs:37:9 | LL | -129..0 => {} | ^^^^ this value does not fit into the type `i8` whose range is `-128..=127` error: literal out of range for `i8` - --> $DIR/validate-range-endpoints.rs:40:9 + --> $DIR/validate-range-endpoints.rs:39:9 | LL | -10000..=-20 => {} | ^^^^^^ this value does not fit into the type `i8` whose range is `-128..=127` error[E0004]: non-exhaustive patterns: `i8::MIN..=-17_i8` and `1_i8..=i8::MAX` not covered - --> $DIR/validate-range-endpoints.rs:51:11 + --> $DIR/validate-range-endpoints.rs:50:11 | LL | match 0i8 { | ^^^ patterns `i8::MIN..=-17_i8` and `1_i8..=i8::MAX` not covered @@ -66,7 +66,7 @@ LL + i8::MIN..=-17_i8 | 1_i8..=i8::MAX => todo!() | error[E0004]: non-exhaustive patterns: `i8::MIN..=-17_i8` not covered - --> $DIR/validate-range-endpoints.rs:55:11 + --> $DIR/validate-range-endpoints.rs:54:11 | LL | match 0i8 { | ^^^ pattern `i8::MIN..=-17_i8` not covered diff --git a/tests/ui/pattern/non-structural-match-types.rs b/tests/ui/pattern/non-structural-match-types.rs index b4f19bb829407..552342a1d3841 100644 --- a/tests/ui/pattern/non-structural-match-types.rs +++ b/tests/ui/pattern/non-structural-match-types.rs @@ -1,6 +1,5 @@ // edition:2021 -#![allow(incomplete_features)] #![allow(unreachable_code)] #![feature(const_async_blocks)] #![feature(inline_const_pat)] diff --git a/tests/ui/pattern/non-structural-match-types.stderr b/tests/ui/pattern/non-structural-match-types.stderr index 4a6990da56f6d..f3e0665fef51d 100644 --- a/tests/ui/pattern/non-structural-match-types.stderr +++ b/tests/ui/pattern/non-structural-match-types.stderr @@ -1,11 +1,11 @@ -error: `{closure@$DIR/non-structural-match-types.rs:10:17: 10:19}` cannot be used in patterns - --> $DIR/non-structural-match-types.rs:10:9 +error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns + --> $DIR/non-structural-match-types.rs:9:9 | LL | const { || {} } => {} | ^^^^^^^^^^^^^^^ -error: `{async block@$DIR/non-structural-match-types.rs:13:17: 13:25}` cannot be used in patterns - --> $DIR/non-structural-match-types.rs:13:9 +error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:25}` cannot be used in patterns + --> $DIR/non-structural-match-types.rs:12:9 | LL | const { async {} } => {} | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unsafe/const_pat_in_layout_restricted.rs b/tests/ui/unsafe/const_pat_in_layout_restricted.rs index 5bc7a7113e4f6..9a085958c1080 100644 --- a/tests/ui/unsafe/const_pat_in_layout_restricted.rs +++ b/tests/ui/unsafe/const_pat_in_layout_restricted.rs @@ -2,7 +2,6 @@ // unsafe because they're within a pattern for a layout constrained stuct. // check-pass -#![allow(incomplete_features)] #![feature(rustc_attrs)] #![feature(inline_const_pat)] From 0148da3528c2b20103566c5c229a596a900ba9d3 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 1 Feb 2024 09:51:29 -0500 Subject: [PATCH 30/35] put pnkfelix (me) back on the review queue. --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index bf898819cfc16..68c863bb919db 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -652,6 +652,7 @@ compiler-team = [ "@davidtwco", "@estebank", "@oli-obk", + "@pnkfelix", "@wesleywiser", "@michaelwoerister", ] From 02320b502d6ae1398126a068cd1efbb96f87faaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 1 Feb 2024 15:58:07 +0100 Subject: [PATCH 31/35] Improve the diagnostics for unused generic parameters --- .../src/error_codes/E0091.md | 6 +- compiler/rustc_hir_analysis/messages.ftl | 11 +++ .../rustc_hir_analysis/src/check/check.rs | 77 +++++++++++++------ .../rustc_hir_analysis/src/check/wfcheck.rs | 64 +++++++-------- compiler/rustc_hir_analysis/src/errors.rs | 24 ++++++ .../generic_arg_infer/infer-arg-test.stderr | 6 +- tests/ui/const-generics/issue-46511.stderr | 4 +- .../issues/issue-67375.min.stderr | 6 +- .../issues/issue-67945-1.min.stderr | 6 +- .../issues/issue-67945-3.min.stderr | 6 +- .../issues/issue-67945-4.min.stderr | 6 +- .../unused-type-param-suggestion.rs | 27 ++++++- .../unused-type-param-suggestion.stderr | 56 ++++++++++++-- .../issue-70453-generics-in-discr-ice.stderr | 6 +- tests/ui/enum/issue-67945-1.stderr | 6 +- tests/ui/enum/issue-67945-2.stderr | 6 +- tests/ui/error-codes/E0091.stderr | 10 ++- tests/ui/error-codes/E0392.stderr | 6 +- tests/ui/inner-static-type-parameter.stderr | 6 +- tests/ui/issues/issue-17904-2.stderr | 4 +- tests/ui/issues/issue-17994.rs | 2 +- tests/ui/issues/issue-17994.stderr | 4 +- tests/ui/issues/issue-20413.stderr | 6 +- tests/ui/issues/issue-30236.rs | 2 +- tests/ui/issues/issue-30236.stderr | 5 +- tests/ui/issues/issue-31910.stderr | 4 +- tests/ui/issues/issue-34373.stderr | 6 +- tests/ui/issues/issue-36299.stderr | 10 +-- tests/ui/issues/issue-37534.stderr | 4 +- .../lang-item-generic-requirements.stderr | 12 +-- .../unused-generic-parameters.rs | 22 ++++++ .../unused-generic-parameters.stderr | 28 +++++++ .../issue-64173-unused-lifetimes.stderr | 8 +- .../item-free-type-bounds-semantic-fail.rs | 4 +- ...item-free-type-bounds-semantic-fail.stderr | 10 ++- ...unds-on-objects-and-type-parameters.stderr | 4 +- .../tilde-const-invalid-places.stderr | 4 +- tests/ui/self/self_type_keyword.stderr | 4 +- tests/ui/tag-type-args.stderr | 6 +- .../variance-regions-unused-direct.stderr | 8 +- .../variance-regions-unused-indirect.stderr | 8 +- .../variance-unused-region-param.stderr | 8 +- .../variance-unused-type-param.stderr | 30 ++++---- 43 files changed, 371 insertions(+), 171 deletions(-) create mode 100644 tests/ui/lazy-type-alias/unused-generic-parameters.rs create mode 100644 tests/ui/lazy-type-alias/unused-generic-parameters.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0091.md b/compiler/rustc_error_codes/src/error_codes/E0091.md index 03cb32803715e..3bf4e907ecb1f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0091.md +++ b/compiler/rustc_error_codes/src/error_codes/E0091.md @@ -1,11 +1,11 @@ -An unnecessary type or const parameter was given in a type alias. +An unnecessary type parameter was given in a type alias. Erroneous code example: ```compile_fail,E0091 -type Foo = u32; // error: type parameter `T` is unused +type Foo = u32; // error: type parameter `T` is never used // or: -type Foo = Box; // error: type parameter `B` is unused +type Foo = Box; // error: type parameter `B` is never used ``` Please check you didn't write too many parameters. Example: diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 432c9c12cbfbc..54d0fb6ffab72 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -434,6 +434,17 @@ hir_analysis_unused_associated_type_bounds = .note = this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`. .suggestion = remove this bound +hir_analysis_unused_generic_parameter = + {$param_def_kind} `{$param_name}` is never used + .label = unused {$param_def_kind} + .const_param_help = if you intended `{$param_name}` to be a const parameter, use `const {$param_name}: /* Type */` instead +hir_analysis_unused_generic_parameter_adt_help = + consider removing `{$param_name}`, referring to it in a field, or using a marker such as `{$phantom_data}` +hir_analysis_unused_generic_parameter_adt_no_phantom_data_help = + consider removing `{$param_name}` or referring to it in a field +hir_analysis_unused_generic_parameter_ty_alias_help = + consider removing `{$param_name}` or referring to it in the body of the type alias + hir_analysis_value_of_associated_struct_already_specified = the value of the associated type `{$item_name}` in trait `{$def_path}` is already specified .label = re-bound here diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 2fe3499e8e690..50809a571b8dc 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -31,6 +31,7 @@ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _}; use rustc_type_ir::fold::TypeFoldable; +use std::cell::LazyCell; use std::ops::ControlFlow; pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) { @@ -520,9 +521,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } DefKind::TyAlias => { - let pty_ty = tcx.type_of(def_id).instantiate_identity(); - let generics = tcx.generics_of(def_id); - check_type_params_are_used(tcx, generics, pty_ty); + check_type_alias_type_params_are_used(tcx, def_id); } DefKind::ForeignMod => { let it = tcx.hir().expect_item(def_id); @@ -1269,28 +1268,51 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) } } -pub(super) fn check_type_params_are_used<'tcx>( - tcx: TyCtxt<'tcx>, - generics: &ty::Generics, - ty: Ty<'tcx>, -) { - debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty); - - assert_eq!(generics.parent, None); +fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { + if tcx.type_alias_is_lazy(def_id) { + // Since we compute the variances for lazy type aliases and already reject bivariant + // parameters as unused, we can and should skip this check for lazy type aliases. + return; + } + let generics = tcx.generics_of(def_id); if generics.own_counts().types == 0 { return; } - let mut params_used = BitSet::new_empty(generics.params.len()); - + let ty = tcx.type_of(def_id).instantiate_identity(); if ty.references_error() { - // If there is already another error, do not emit - // an error for not using a type parameter. + // If there is already another error, do not emit an error for not using a type parameter. assert!(tcx.dcx().has_errors().is_some()); return; } + // Lazily calculated because it is only needed in case of an error. + let bounded_params = LazyCell::new(|| { + tcx.explicit_predicates_of(def_id) + .predicates + .iter() + .filter_map(|(predicate, span)| { + let bounded_ty = match predicate.kind().skip_binder() { + ty::ClauseKind::Trait(pred) => pred.trait_ref.self_ty(), + ty::ClauseKind::TypeOutlives(pred) => pred.0, + _ => return None, + }; + if let ty::Param(param) = bounded_ty.kind() { + Some((param.index, span)) + } else { + None + } + }) + // FIXME: This assumes that elaborated `Sized` bounds come first (which does hold at the + // time of writing). This is a bit fragile since we later use the span to detect elaborated + // `Sized` bounds. If they came last for example, this would break `Trait + /*elab*/Sized` + // since it would overwrite the span of the user-written bound. This could be fixed by + // folding the spans with `Span::to` which requires a bit of effort I think. + .collect::>() + }); + + let mut params_used = BitSet::new_empty(generics.params.len()); for leaf in ty.walk() { if let GenericArgKind::Type(leaf_ty) = leaf.unpack() && let ty::Param(param) = leaf_ty.kind() @@ -1305,15 +1327,24 @@ pub(super) fn check_type_params_are_used<'tcx>( && let ty::GenericParamDefKind::Type { .. } = param.kind { let span = tcx.def_span(param.def_id); - struct_span_code_err!( - tcx.dcx(), + let param_name = Ident::new(param.name, span); + + // The corresponding predicates are post-`Sized`-elaboration. Therefore we + // * check for emptiness to detect lone user-written `?Sized` bounds + // * compare the param span to the pred span to detect lone user-written `Sized` bounds + let has_explicit_bounds = bounded_params.is_empty() + || (*bounded_params).get(¶m.index).is_some_and(|&&pred_sp| pred_sp != span); + let const_param_help = (!has_explicit_bounds).then_some(()); + + let mut diag = tcx.dcx().create_err(errors::UnusedGenericParameter { span, - E0091, - "type parameter `{}` is unused", - param.name, - ) - .with_span_label(span, "unused type parameter") - .emit(); + param_name, + param_def_kind: tcx.def_descr(param.def_id), + help: errors::UnusedGenericParameterHelp::TyAlias { param_name }, + const_param_help, + }); + diag.code(E0091); + diag.emit(); } } } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b9c9eec28139a..07f798dcbda22 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1,11 +1,10 @@ use crate::autoderef::Autoderef; use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; +use crate::errors; use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; -use rustc_errors::{ - codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, -}; +use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::lang_items::LangItem; @@ -21,7 +20,7 @@ use rustc_middle::ty::{ }; use rustc_middle::ty::{GenericArgKind, GenericArgs}; use rustc_session::parse::feature_err; -use rustc_span::symbol::{sym, Ident, Symbol}; +use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::regions::InferCtxtRegionExt; @@ -1869,7 +1868,7 @@ fn check_variances_for_type_defn<'tcx>( hir::ParamName::Error => {} _ => { let has_explicit_bounds = explicitly_bounded_params.contains(¶meter); - report_bivariance(tcx, hir_param, has_explicit_bounds); + report_bivariance(tcx, hir_param, has_explicit_bounds, item.kind); } } } @@ -1879,30 +1878,38 @@ fn report_bivariance( tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>, has_explicit_bounds: bool, + item_kind: ItemKind<'_>, ) -> ErrorGuaranteed { - let span = param.span; - let param_name = param.name.ident().name; - let mut err = error_392(tcx, span, param_name); - - let suggested_marker_id = tcx.lang_items().phantom_data(); - // Help is available only in presence of lang items. - let msg = if let Some(def_id) = suggested_marker_id { - format!( - "consider removing `{}`, referring to it in a field, or using a marker such as `{}`", - param_name, - tcx.def_path_str(def_id), - ) - } else { - format!("consider removing `{param_name}` or referring to it in a field") + let param_name = param.name.ident(); + + let help = match item_kind { + ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => { + if let Some(def_id) = tcx.lang_items().phantom_data() { + errors::UnusedGenericParameterHelp::Adt { + param_name, + phantom_data: tcx.def_path_str(def_id), + } + } else { + errors::UnusedGenericParameterHelp::AdtNoPhantomData { param_name } + } + } + ItemKind::TyAlias(..) => errors::UnusedGenericParameterHelp::TyAlias { param_name }, + item_kind => bug!("report_bivariance: unexpected item kind: {item_kind:?}"), }; - err.help(msg); - if matches!(param.kind, hir::GenericParamKind::Type { .. }) && !has_explicit_bounds { - err.help(format!( - "if you intended `{param_name}` to be a const parameter, use `const {param_name}: usize` instead" - )); - } - err.emit() + let const_param_help = + matches!(param.kind, hir::GenericParamKind::Type { .. } if !has_explicit_bounds) + .then_some(()); + + let mut diag = tcx.dcx().create_err(errors::UnusedGenericParameter { + span: param.span, + param_name, + param_def_kind: tcx.def_descr(param.def_id.to_def_id()), + help, + const_param_help, + }); + diag.code(E0392); + diag.emit() } impl<'tcx> WfCheckingCtxt<'_, 'tcx> { @@ -1967,11 +1974,6 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error res } -fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> { - struct_span_code_err!(tcx.dcx(), span, E0392, "parameter `{param_name}` is never used") - .with_span_label(span, "unused parameter") -} - pub fn provide(providers: &mut Providers) { *providers = Providers { check_mod_type_wf, check_well_formed, ..*providers }; } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index e5871276d6414..4eba31e327f68 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1511,3 +1511,27 @@ pub struct NotSupportedDelegation<'a> { #[label] pub callee_span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_unused_generic_parameter)] +pub(crate) struct UnusedGenericParameter { + #[primary_span] + #[label] + pub span: Span, + pub param_name: Ident, + pub param_def_kind: &'static str, + #[subdiagnostic] + pub help: UnusedGenericParameterHelp, + #[help(hir_analysis_const_param_help)] + pub const_param_help: Option<()>, +} + +#[derive(Subdiagnostic)] +pub(crate) enum UnusedGenericParameterHelp { + #[help(hir_analysis_unused_generic_parameter_adt_help)] + Adt { param_name: Ident, phantom_data: String }, + #[help(hir_analysis_unused_generic_parameter_adt_no_phantom_data_help)] + AdtNoPhantomData { param_name: Ident }, + #[help(hir_analysis_unused_generic_parameter_ty_alias_help)] + TyAlias { param_name: Ident }, +} diff --git a/tests/ui/const-generics/generic_arg_infer/infer-arg-test.stderr b/tests/ui/const-generics/generic_arg_infer/infer-arg-test.stderr index a6b736261e09c..6d8dd017734c0 100644 --- a/tests/ui/const-generics/generic_arg_infer/infer-arg-test.stderr +++ b/tests/ui/const-generics/generic_arg_infer/infer-arg-test.stderr @@ -10,14 +10,14 @@ error: expected identifier, found reserved identifier `_` LL | fn bad_infer_fn<_>() {} | ^ expected identifier, found reserved identifier -error[E0392]: parameter `_` is never used +error[E0392]: type parameter `_` is never used --> $DIR/infer-arg-test.rs:7:17 | LL | struct BadInfer<_>; - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `_` to be a const parameter, use `const _: usize` instead + = help: if you intended `_` to be a const parameter, use `const _: /* Type */` instead error[E0107]: struct takes 2 generic arguments but 3 generic arguments were supplied --> $DIR/infer-arg-test.rs:18:10 diff --git a/tests/ui/const-generics/issue-46511.stderr b/tests/ui/const-generics/issue-46511.stderr index d57295fa2fae1..75d59ee40b3b7 100644 --- a/tests/ui/const-generics/issue-46511.stderr +++ b/tests/ui/const-generics/issue-46511.stderr @@ -7,11 +7,11 @@ LL | _a: [u8; std::mem::size_of::<&'a mut u8>()] = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0392]: parameter `'a` is never used +error[E0392]: lifetime parameter `'a` is never used --> $DIR/issue-46511.rs:3:12 | LL | struct Foo<'a> - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/const-generics/issues/issue-67375.min.stderr b/tests/ui/const-generics/issues/issue-67375.min.stderr index 7671e3c468876..e871203ed9b89 100644 --- a/tests/ui/const-generics/issues/issue-67375.min.stderr +++ b/tests/ui/const-generics/issues/issue-67375.min.stderr @@ -7,14 +7,14 @@ LL | inner: [(); { [|_: &T| {}; 0].len() }], = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/issue-67375.rs:5:12 | LL | struct Bug { - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `T` to be a const parameter, use `const T: usize` instead + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-67945-1.min.stderr b/tests/ui/const-generics/issues/issue-67945-1.min.stderr index 1d071da903fa1..1de607644f570 100644 --- a/tests/ui/const-generics/issues/issue-67945-1.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-1.min.stderr @@ -16,14 +16,14 @@ LL | let b = &*(&x as *const _ as *const S); = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0392]: parameter `S` is never used +error[E0392]: type parameter `S` is never used --> $DIR/issue-67945-1.rs:7:12 | LL | struct Bug { - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `S` to be a const parameter, use `const S: usize` instead + = help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/issues/issue-67945-3.min.stderr b/tests/ui/const-generics/issues/issue-67945-3.min.stderr index e34869c79386b..0ccba18e953cf 100644 --- a/tests/ui/const-generics/issues/issue-67945-3.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-3.min.stderr @@ -7,14 +7,14 @@ LL | let x: Option = None; = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0392]: parameter `S` is never used +error[E0392]: type parameter `S` is never used --> $DIR/issue-67945-3.rs:9:12 | LL | struct Bug { - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `S` to be a const parameter, use `const S: usize` instead + = help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-67945-4.min.stderr b/tests/ui/const-generics/issues/issue-67945-4.min.stderr index 280c6f4f2cdfe..83ae68e2dbf0e 100644 --- a/tests/ui/const-generics/issues/issue-67945-4.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-4.min.stderr @@ -7,14 +7,14 @@ LL | let x: Option> = None; = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0392]: parameter `S` is never used +error[E0392]: type parameter `S` is never used --> $DIR/issue-67945-4.rs:8:12 | LL | struct Bug { - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `S` to be a const parameter, use `const S: usize` instead + = help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/unused-type-param-suggestion.rs b/tests/ui/const-generics/unused-type-param-suggestion.rs index 2251512c4596e..fb0ccb4fdcd72 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.rs +++ b/tests/ui/const-generics/unused-type-param-suggestion.rs @@ -1,4 +1,27 @@ #![crate_type="lib"] -struct Example; -//~^ ERROR parameter +struct S; +//~^ ERROR type parameter `N` is never used +//~| HELP consider removing `N` +//~| HELP if you intended `N` to be a const parameter + +// Ensure that we don't emit the const param suggestion here: +struct T; +//~^ ERROR type parameter `N` is never used +//~| HELP consider removing `N` + +type A = (); +//~^ ERROR type parameter `N` is never used +//~| HELP consider removing `N` +//~| HELP if you intended `N` to be a const parameter + +// Ensure that we don't emit the const param suggestion here: +type B = (); +//~^ ERROR type parameter `N` is never used +//~| HELP consider removing `N` +type C = (); +//~^ ERROR type parameter `N` is never used +//~| HELP consider removing `N` +type D = (); +//~^ ERROR type parameter `N` is never used +//~| HELP consider removing `N` diff --git a/tests/ui/const-generics/unused-type-param-suggestion.stderr b/tests/ui/const-generics/unused-type-param-suggestion.stderr index 6e985f56666bd..67b704d8bc725 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.stderr +++ b/tests/ui/const-generics/unused-type-param-suggestion.stderr @@ -1,12 +1,54 @@ -error[E0392]: parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:3:16 +error[E0392]: type parameter `N` is never used + --> $DIR/unused-type-param-suggestion.rs:3:10 | -LL | struct Example; - | ^ unused parameter +LL | struct S; + | ^ unused type parameter | = help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `N` to be a const parameter, use `const N: usize` instead + = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead -error: aborting due to 1 previous error +error[E0392]: type parameter `N` is never used + --> $DIR/unused-type-param-suggestion.rs:9:10 + | +LL | struct T; + | ^ unused type parameter + | + = help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0091]: type parameter `N` is never used + --> $DIR/unused-type-param-suggestion.rs:13:8 + | +LL | type A = (); + | ^ unused type parameter + | + = help: consider removing `N` or referring to it in the body of the type alias + = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead + +error[E0091]: type parameter `N` is never used + --> $DIR/unused-type-param-suggestion.rs:19:8 + | +LL | type B = (); + | ^ unused type parameter + | + = help: consider removing `N` or referring to it in the body of the type alias + +error[E0091]: type parameter `N` is never used + --> $DIR/unused-type-param-suggestion.rs:22:8 + | +LL | type C = (); + | ^ unused type parameter + | + = help: consider removing `N` or referring to it in the body of the type alias + +error[E0091]: type parameter `N` is never used + --> $DIR/unused-type-param-suggestion.rs:25:8 + | +LL | type D = (); + | ^ unused type parameter + | + = help: consider removing `N` or referring to it in the body of the type alias + +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0392`. +Some errors have detailed explanations: E0091, E0392. +For more information about an error, try `rustc --explain E0091`. diff --git a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr index fac3ce07aeb92..1341b03cb56e4 100644 --- a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr +++ b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr @@ -6,14 +6,14 @@ LL | Some = std::mem::size_of::(), | = note: type parameters may not be used in enum discriminant values -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/issue-70453-generics-in-discr-ice.rs:7:20 | LL | enum MyWeirdOption { - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `T` to be a const parameter, use `const T: usize` instead + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/enum/issue-67945-1.stderr b/tests/ui/enum/issue-67945-1.stderr index 878fa322f02d5..ce0ea77763663 100644 --- a/tests/ui/enum/issue-67945-1.stderr +++ b/tests/ui/enum/issue-67945-1.stderr @@ -6,14 +6,14 @@ LL | let x: S = 0; | = note: type parameters may not be used in enum discriminant values -error[E0392]: parameter `S` is never used +error[E0392]: type parameter `S` is never used --> $DIR/issue-67945-1.rs:1:10 | LL | enum Bug { - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `S` to be a const parameter, use `const S: usize` instead + = help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/enum/issue-67945-2.stderr b/tests/ui/enum/issue-67945-2.stderr index f8ec12d470acf..96bd08f841a40 100644 --- a/tests/ui/enum/issue-67945-2.stderr +++ b/tests/ui/enum/issue-67945-2.stderr @@ -6,14 +6,14 @@ LL | Var = type_ascribe!(0, S), | = note: type parameters may not be used in enum discriminant values -error[E0392]: parameter `S` is never used +error[E0392]: type parameter `S` is never used --> $DIR/issue-67945-2.rs:3:10 | LL | enum Bug { - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `S` to be a const parameter, use `const S: usize` instead + = help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0091.stderr b/tests/ui/error-codes/E0091.stderr index a596b75e481de..c1427ec66863a 100644 --- a/tests/ui/error-codes/E0091.stderr +++ b/tests/ui/error-codes/E0091.stderr @@ -1,14 +1,20 @@ -error[E0091]: type parameter `T` is unused +error[E0091]: type parameter `T` is never used --> $DIR/E0091.rs:1:10 | LL | type Foo = u32; | ^ unused type parameter + | + = help: consider removing `T` or referring to it in the body of the type alias + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error[E0091]: type parameter `B` is unused +error[E0091]: type parameter `B` is never used --> $DIR/E0091.rs:2:14 | LL | type Foo2 = Box; | ^ unused type parameter + | + = help: consider removing `B` or referring to it in the body of the type alias + = help: if you intended `B` to be a const parameter, use `const B: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0392.stderr b/tests/ui/error-codes/E0392.stderr index ecbfd5584d5a3..9971267e9270d 100644 --- a/tests/ui/error-codes/E0392.stderr +++ b/tests/ui/error-codes/E0392.stderr @@ -1,11 +1,11 @@ -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/E0392.rs:1:10 | LL | enum Foo { Bar } - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `T` to be a const parameter, use `const T: usize` instead + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error: aborting due to 1 previous error diff --git a/tests/ui/inner-static-type-parameter.stderr b/tests/ui/inner-static-type-parameter.stderr index ff6558e494b11..6c7f1ffbe1690 100644 --- a/tests/ui/inner-static-type-parameter.stderr +++ b/tests/ui/inner-static-type-parameter.stderr @@ -6,14 +6,14 @@ LL | fn foo() { LL | static a: Bar = Bar::What; | ^ use of generic parameter from outer item -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/inner-static-type-parameter.rs:3:10 | LL | enum Bar { What } - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `T` to be a const parameter, use `const T: usize` instead + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-17904-2.stderr b/tests/ui/issues/issue-17904-2.stderr index 102c8537f8e04..9965106d1401a 100644 --- a/tests/ui/issues/issue-17904-2.stderr +++ b/tests/ui/issues/issue-17904-2.stderr @@ -1,8 +1,8 @@ -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/issue-17904-2.rs:4:12 | LL | struct Foo where T: Copy; - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/issues/issue-17994.rs b/tests/ui/issues/issue-17994.rs index 39b0a7ebe74d8..ab37a172eaa74 100644 --- a/tests/ui/issues/issue-17994.rs +++ b/tests/ui/issues/issue-17994.rs @@ -1,3 +1,3 @@ trait Tr {} -type Huh where T: Tr = isize; //~ ERROR type parameter `T` is unused +type Huh where T: Tr = isize; //~ ERROR type parameter `T` is never used fn main() {} diff --git a/tests/ui/issues/issue-17994.stderr b/tests/ui/issues/issue-17994.stderr index ba3def64dfb5d..f149e5d08faac 100644 --- a/tests/ui/issues/issue-17994.stderr +++ b/tests/ui/issues/issue-17994.stderr @@ -1,8 +1,10 @@ -error[E0091]: type parameter `T` is unused +error[E0091]: type parameter `T` is never used --> $DIR/issue-17994.rs:2:10 | LL | type Huh where T: Tr = isize; | ^ unused type parameter + | + = help: consider removing `T` or referring to it in the body of the type alias error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-20413.stderr b/tests/ui/issues/issue-20413.stderr index 8793029dd224a..5d442eb989851 100644 --- a/tests/ui/issues/issue-20413.stderr +++ b/tests/ui/issues/issue-20413.stderr @@ -1,11 +1,11 @@ -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/issue-20413.rs:6:15 | LL | struct NoData; - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `T` to be a const parameter, use `const T: usize` instead + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error[E0275]: overflow evaluating the requirement `NoData>>>>>>: Foo` --> $DIR/issue-20413.rs:9:36 diff --git a/tests/ui/issues/issue-30236.rs b/tests/ui/issues/issue-30236.rs index 9c2d855076d79..08d08a544021e 100644 --- a/tests/ui/issues/issue-30236.rs +++ b/tests/ui/issues/issue-30236.rs @@ -1,5 +1,5 @@ type Foo< - Unused //~ ERROR type parameter `Unused` is unused + Unused //~ ERROR type parameter `Unused` is never used > = u8; fn main() { diff --git a/tests/ui/issues/issue-30236.stderr b/tests/ui/issues/issue-30236.stderr index 0f69f49f505a0..bfe374a653f5f 100644 --- a/tests/ui/issues/issue-30236.stderr +++ b/tests/ui/issues/issue-30236.stderr @@ -1,8 +1,11 @@ -error[E0091]: type parameter `Unused` is unused +error[E0091]: type parameter `Unused` is never used --> $DIR/issue-30236.rs:2:5 | LL | Unused | ^^^^^^ unused type parameter + | + = help: consider removing `Unused` or referring to it in the body of the type alias + = help: if you intended `Unused` to be a const parameter, use `const Unused: /* Type */` instead error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-31910.stderr b/tests/ui/issues/issue-31910.stderr index 89a6d5574a1e5..ca2d2f619e62e 100644 --- a/tests/ui/issues/issue-31910.stderr +++ b/tests/ui/issues/issue-31910.stderr @@ -4,11 +4,11 @@ error[E0308]: mismatched types LL | X = Trait::Number, | ^^^^^^^^^^^^^ expected `isize`, found `i32` -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/issue-31910.rs:1:11 | LL | enum Enum { - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/issues/issue-34373.stderr index 1a1cfc925b779..13667cd920e9b 100644 --- a/tests/ui/issues/issue-34373.stderr +++ b/tests/ui/issues/issue-34373.stderr @@ -45,14 +45,14 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o LL | fn foo(_: T) where Self: Sized {} | +++++++++++++++++ -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/issue-34373.rs:7:16 | LL | pub struct Foo>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unused parameter + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `T` to be a const parameter, use `const T: usize` instead + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-36299.stderr b/tests/ui/issues/issue-36299.stderr index dc24fb353f408..29e8d7ca59a24 100644 --- a/tests/ui/issues/issue-36299.stderr +++ b/tests/ui/issues/issue-36299.stderr @@ -1,19 +1,19 @@ -error[E0392]: parameter `'a` is never used +error[E0392]: lifetime parameter `'a` is never used --> $DIR/issue-36299.rs:1:12 | LL | struct Foo<'a, A> {} - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` -error[E0392]: parameter `A` is never used +error[E0392]: type parameter `A` is never used --> $DIR/issue-36299.rs:1:16 | LL | struct Foo<'a, A> {} - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `A`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `A` to be a const parameter, use `const A: usize` instead + = help: if you intended `A` to be a const parameter, use `const A: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-37534.stderr b/tests/ui/issues/issue-37534.stderr index 03fea2c16486d..a687e733d3dae 100644 --- a/tests/ui/issues/issue-37534.stderr +++ b/tests/ui/issues/issue-37534.stderr @@ -15,11 +15,11 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr LL | struct Foo {} | ^^^^^ -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/issue-37534.rs:1:12 | LL | struct Foo {} - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr index 8072e6797e49c..30abdf84046ea 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.stderr +++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr @@ -50,23 +50,23 @@ LL | LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize { | - this function has 0 generic arguments -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/lang-item-generic-requirements.rs:24:22 | LL | struct MyPhantomData; - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T` or referring to it in a field - = help: if you intended `T` to be a const parameter, use `const T: usize` instead + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error[E0392]: parameter `U` is never used +error[E0392]: type parameter `U` is never used --> $DIR/lang-item-generic-requirements.rs:24:25 | LL | struct MyPhantomData; - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `U` or referring to it in a field - = help: if you intended `U` to be a const parameter, use `const U: usize` instead + = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead error[E0369]: cannot add `{integer}` to `{integer}` --> $DIR/lang-item-generic-requirements.rs:44:7 diff --git a/tests/ui/lazy-type-alias/unused-generic-parameters.rs b/tests/ui/lazy-type-alias/unused-generic-parameters.rs new file mode 100644 index 0000000000000..9d02de7a7212b --- /dev/null +++ b/tests/ui/lazy-type-alias/unused-generic-parameters.rs @@ -0,0 +1,22 @@ +// Check that we reject bivariant generic parameters as unused. +// Furthermore, check that we only emit a single diagnostic for unused type parameters: +// Previously, we would emit *two* errors, namely E0392 and E0091. + +#![feature(lazy_type_alias)] +#![allow(incomplete_features)] + +type A<'a> = (); +//~^ ERROR lifetime parameter `'a` is never used +//~| HELP consider removing `'a` + +type B = (); +//~^ ERROR type parameter `T` is never used +//~| HELP consider removing `T` +//~| HELP if you intended `T` to be a const parameter + +// Check that we don't emit the const param help message here: +type C = (); +//~^ ERROR type parameter `T` is never used +//~| HELP consider removing `T` + +fn main() {} diff --git a/tests/ui/lazy-type-alias/unused-generic-parameters.stderr b/tests/ui/lazy-type-alias/unused-generic-parameters.stderr new file mode 100644 index 0000000000000..484e21b0a03f9 --- /dev/null +++ b/tests/ui/lazy-type-alias/unused-generic-parameters.stderr @@ -0,0 +1,28 @@ +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/unused-generic-parameters.rs:8:8 + | +LL | type A<'a> = (); + | ^^ unused lifetime parameter + | + = help: consider removing `'a` or referring to it in the body of the type alias + +error[E0392]: type parameter `T` is never used + --> $DIR/unused-generic-parameters.rs:12:8 + | +LL | type B = (); + | ^ unused type parameter + | + = help: consider removing `T` or referring to it in the body of the type alias + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead + +error[E0392]: type parameter `T` is never used + --> $DIR/unused-generic-parameters.rs:18:8 + | +LL | type C = (); + | ^ unused type parameter + | + = help: consider removing `T` or referring to it in the body of the type alias + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0392`. diff --git a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr index ec4aea623911a..534ba933ba5d0 100644 --- a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr +++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr @@ -13,19 +13,19 @@ error: generic `Self` types are currently not permitted in anonymous constants LL | array: [(); size_of::<&Self>()], | ^^^^ -error[E0392]: parameter `'s` is never used +error[E0392]: lifetime parameter `'s` is never used --> $DIR/issue-64173-unused-lifetimes.rs:3:12 | LL | struct Foo<'s> { - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'s`, referring to it in a field, or using a marker such as `PhantomData` -error[E0392]: parameter `'a` is never used +error[E0392]: lifetime parameter `'a` is never used --> $DIR/issue-64173-unused-lifetimes.rs:15:12 | LL | struct Bar<'a> { - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/parser/item-free-type-bounds-semantic-fail.rs b/tests/ui/parser/item-free-type-bounds-semantic-fail.rs index 9db4111fbabd9..062b51e597845 100644 --- a/tests/ui/parser/item-free-type-bounds-semantic-fail.rs +++ b/tests/ui/parser/item-free-type-bounds-semantic-fail.rs @@ -13,8 +13,8 @@ fn semantics() { //~| ERROR free type alias without body type E<_T>: Ord = u8; //~^ ERROR bounds on `type`s in this context have no effect - //~| ERROR type parameter `_T` is unused + //~| ERROR type parameter `_T` is never used type F<_T>: Ord where 'static: 'static = u8; //~^ ERROR bounds on `type`s in this context have no effect - //~| ERROR type parameter `_T` is unused + //~| ERROR type parameter `_T` is never used } diff --git a/tests/ui/parser/item-free-type-bounds-semantic-fail.stderr b/tests/ui/parser/item-free-type-bounds-semantic-fail.stderr index 1b086512891f2..1077c10392888 100644 --- a/tests/ui/parser/item-free-type-bounds-semantic-fail.stderr +++ b/tests/ui/parser/item-free-type-bounds-semantic-fail.stderr @@ -50,17 +50,23 @@ error: bounds on `type`s in this context have no effect LL | type F<_T>: Ord where 'static: 'static = u8; | ^^^ -error[E0091]: type parameter `_T` is unused +error[E0091]: type parameter `_T` is never used --> $DIR/item-free-type-bounds-semantic-fail.rs:14:12 | LL | type E<_T>: Ord = u8; | ^^ unused type parameter + | + = help: consider removing `_T` or referring to it in the body of the type alias + = help: if you intended `_T` to be a const parameter, use `const _T: /* Type */` instead -error[E0091]: type parameter `_T` is unused +error[E0091]: type parameter `_T` is never used --> $DIR/item-free-type-bounds-semantic-fail.rs:17:12 | LL | type F<_T>: Ord where 'static: 'static = u8; | ^^ unused type parameter + | + = help: consider removing `_T` or referring to it in the body of the type alias + = help: if you intended `_T` to be a const parameter, use `const _T: /* Type */` instead error: aborting due to 10 previous errors diff --git a/tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr b/tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr index 2ec2ca49b1142..b15d2affeea37 100644 --- a/tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr +++ b/tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr @@ -21,11 +21,11 @@ note: but lifetime parameter must outlive the lifetime `'a` as defined here LL | struct Foo<'a,'b,'c> { | ^^ -error[E0392]: parameter `'c` is never used +error[E0392]: lifetime parameter `'c` is never used --> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:18 | LL | struct Foo<'a,'b,'c> { - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index d57f5702a6382..92a9c347a075e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -272,11 +272,11 @@ LL | type Type = (); = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/tilde-const-invalid-places.rs:11:19 | LL | struct UnitStruct; - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr index fed853a7e1fd8..4909a9cdc7f5c 100644 --- a/tests/ui/self/self_type_keyword.stderr +++ b/tests/ui/self/self_type_keyword.stderr @@ -72,11 +72,11 @@ note: unit struct `foo::Self` exists but is inaccessible LL | struct Self; | ^^^^^^^^^^^^ not accessible -error[E0392]: parameter `'Self` is never used +error[E0392]: lifetime parameter `'Self` is never used --> $DIR/self_type_keyword.rs:6:12 | LL | struct Bar<'Self>; - | ^^^^^ unused parameter + | ^^^^^ unused lifetime parameter | = help: consider removing `'Self`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/tag-type-args.stderr b/tests/ui/tag-type-args.stderr index 80ffd3a2f0500..a1136f61cc52f 100644 --- a/tests/ui/tag-type-args.stderr +++ b/tests/ui/tag-type-args.stderr @@ -14,14 +14,14 @@ help: add missing generic argument LL | fn foo(c: Quux) { assert!((false)); } | +++ -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/tag-type-args.rs:1:11 | LL | enum Quux { Bar } - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `T` to be a const parameter, use `const T: usize` instead + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error: aborting due to 2 previous errors diff --git a/tests/ui/variance/variance-regions-unused-direct.stderr b/tests/ui/variance/variance-regions-unused-direct.stderr index 1a600f5b0580f..4dc2af6ce2cc8 100644 --- a/tests/ui/variance/variance-regions-unused-direct.stderr +++ b/tests/ui/variance/variance-regions-unused-direct.stderr @@ -1,16 +1,16 @@ -error[E0392]: parameter `'a` is never used +error[E0392]: lifetime parameter `'a` is never used --> $DIR/variance-regions-unused-direct.rs:5:18 | LL | struct Bivariant<'a>; - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` -error[E0392]: parameter `'d` is never used +error[E0392]: lifetime parameter `'d` is never used --> $DIR/variance-regions-unused-direct.rs:7:19 | LL | struct Struct<'a, 'd> { - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'d`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/variance/variance-regions-unused-indirect.stderr b/tests/ui/variance/variance-regions-unused-indirect.stderr index 14fdd849294b1..ec4d480baab78 100644 --- a/tests/ui/variance/variance-regions-unused-indirect.stderr +++ b/tests/ui/variance/variance-regions-unused-indirect.stderr @@ -21,19 +21,19 @@ LL | enum Bar<'a> { LL ~ Bar1(Box>) | -error[E0392]: parameter `'a` is never used +error[E0392]: lifetime parameter `'a` is never used --> $DIR/variance-regions-unused-indirect.rs:3:10 | LL | enum Foo<'a> { - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` -error[E0392]: parameter `'a` is never used +error[E0392]: lifetime parameter `'a` is never used --> $DIR/variance-regions-unused-indirect.rs:8:10 | LL | enum Bar<'a> { - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/variance/variance-unused-region-param.stderr b/tests/ui/variance/variance-unused-region-param.stderr index 7c7ec40ba35c3..b9c08bd43c454 100644 --- a/tests/ui/variance/variance-unused-region-param.stderr +++ b/tests/ui/variance/variance-unused-region-param.stderr @@ -1,16 +1,16 @@ -error[E0392]: parameter `'a` is never used +error[E0392]: lifetime parameter `'a` is never used --> $DIR/variance-unused-region-param.rs:3:19 | LL | struct SomeStruct<'a> { x: u32 } - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` -error[E0392]: parameter `'a` is never used +error[E0392]: lifetime parameter `'a` is never used --> $DIR/variance-unused-region-param.rs:4:15 | LL | enum SomeEnum<'a> { Nothing } - | ^^ unused parameter + | ^^ unused lifetime parameter | = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` diff --git a/tests/ui/variance/variance-unused-type-param.stderr b/tests/ui/variance/variance-unused-type-param.stderr index e612da118f058..3011b7bd18fa7 100644 --- a/tests/ui/variance/variance-unused-type-param.stderr +++ b/tests/ui/variance/variance-unused-type-param.stderr @@ -1,51 +1,51 @@ -error[E0392]: parameter `A` is never used +error[E0392]: type parameter `A` is never used --> $DIR/variance-unused-type-param.rs:6:19 | LL | struct SomeStruct { x: u32 } - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `A`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `A` to be a const parameter, use `const A: usize` instead + = help: if you intended `A` to be a const parameter, use `const A: /* Type */` instead -error[E0392]: parameter `A` is never used +error[E0392]: type parameter `A` is never used --> $DIR/variance-unused-type-param.rs:9:15 | LL | enum SomeEnum { Nothing } - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `A`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `A` to be a const parameter, use `const A: usize` instead + = help: if you intended `A` to be a const parameter, use `const A: /* Type */` instead -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/variance-unused-type-param.rs:13:15 | LL | enum ListCell { - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `T` to be a const parameter, use `const T: usize` instead + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/variance-unused-type-param.rs:19:19 | LL | struct WithBounds {} - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/variance-unused-type-param.rs:22:24 | LL | struct WithWhereBounds where T: Sized {} - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` -error[E0392]: parameter `T` is never used +error[E0392]: type parameter `T` is never used --> $DIR/variance-unused-type-param.rs:25:27 | LL | struct WithOutlivesBounds {} - | ^ unused parameter + | ^ unused type parameter | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` From bedd81ef2afdf5979e316cde4c664bd13d49b266 Mon Sep 17 00:00:00 2001 From: Jeremiah Senkpiel Date: Wed, 31 Jan 2024 16:58:35 -0800 Subject: [PATCH 32/35] add test for try-block-in-match-arm This is noted as an implementation concern under the tracking issue for `?` and `try` blocks. (Issue 31436) --- tests/ui/try-block/try-block-in-match-arm.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/ui/try-block/try-block-in-match-arm.rs diff --git a/tests/ui/try-block/try-block-in-match-arm.rs b/tests/ui/try-block/try-block-in-match-arm.rs new file mode 100644 index 0000000000000..ea004ebe29f9e --- /dev/null +++ b/tests/ui/try-block/try-block-in-match-arm.rs @@ -0,0 +1,11 @@ +// check-pass +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +fn main() { + let _ = match 1 { + 1 => try {} + _ => Ok::<(), ()>(()), + }; +} From 2c0030ff2cb373a31d4dfa7f7cb3596739090ff3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 1 Feb 2024 14:56:41 +0100 Subject: [PATCH 33/35] Correctly check `never_type` feature gating --- compiler/rustc_ast_passes/src/feature_gate.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 82236d2e30678..409aef9185d92 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -362,6 +362,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } + fn visit_generic_args(&mut self, args: &'a ast::GenericArgs) { + // This check needs to happen here because the never type can be returned from a function, + // but cannot be used in any other context. If this check was in `visit_fn_ret_ty`, it + // include both functions and generics like `impl Fn() -> !`. + if let ast::GenericArgs::Parenthesized(generic_args) = args + && let ast::FnRetTy::Ty(ref ty) = generic_args.output + && matches!(ty.kind, ast::TyKind::Never) + { + gate!(&self, never_type, ty.span, "the `!` type is experimental"); + } + visit::walk_generic_args(self, args); + } + fn visit_expr(&mut self, e: &'a ast::Expr) { match e.kind { ast::ExprKind::TryBlock(_) => { From 0f21e45e95ea879ec13a690390c9d0bd327bfe58 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 1 Feb 2024 14:57:01 +0100 Subject: [PATCH 34/35] Update `never_type` feature gate ui test --- .../feature-gates/feature-gate-never_type.rs | 9 ++++++ .../feature-gate-never_type.stderr | 32 ++++++++++++++++++- .../never-type-in-nested-fn-decl.rs | 7 ++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/ui/never_type/never-type-in-nested-fn-decl.rs diff --git a/tests/ui/feature-gates/feature-gate-never_type.rs b/tests/ui/feature-gates/feature-gate-never_type.rs index be8c27dbb1b02..f5d28a4877fdf 100644 --- a/tests/ui/feature-gates/feature-gate-never_type.rs +++ b/tests/ui/feature-gates/feature-gate-never_type.rs @@ -13,5 +13,14 @@ impl Foo for Meeshka { type Wub = !; //~ ERROR type is experimental } +fn look_ma_no_feature_gate !>() {} //~ ERROR type is experimental +fn tadam(f: &dyn Fn() -> !) {} //~ ERROR type is experimental +fn panic() -> ! { + panic!(); +} +fn toudoum() -> impl Fn() -> ! { //~ ERROR type is experimental + panic +} + fn main() { } diff --git a/tests/ui/feature-gates/feature-gate-never_type.stderr b/tests/ui/feature-gates/feature-gate-never_type.stderr index 0fca58519ce13..33e4e019b18d3 100644 --- a/tests/ui/feature-gates/feature-gate-never_type.stderr +++ b/tests/ui/feature-gates/feature-gate-never_type.stderr @@ -48,6 +48,36 @@ LL | type Wub = !; = help: add `#![feature(never_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 5 previous errors +error[E0658]: the `!` type is experimental + --> $DIR/feature-gate-never_type.rs:16:43 + | +LL | fn look_ma_no_feature_gate !>() {} + | ^ + | + = note: see issue #35121 for more information + = help: add `#![feature(never_type)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `!` type is experimental + --> $DIR/feature-gate-never_type.rs:17:26 + | +LL | fn tadam(f: &dyn Fn() -> !) {} + | ^ + | + = note: see issue #35121 for more information + = help: add `#![feature(never_type)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `!` type is experimental + --> $DIR/feature-gate-never_type.rs:21:30 + | +LL | fn toudoum() -> impl Fn() -> ! { + | ^ + | + = note: see issue #35121 for more information + = help: add `#![feature(never_type)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/never_type/never-type-in-nested-fn-decl.rs b/tests/ui/never_type/never-type-in-nested-fn-decl.rs new file mode 100644 index 0000000000000..df546c4717eb6 --- /dev/null +++ b/tests/ui/never_type/never-type-in-nested-fn-decl.rs @@ -0,0 +1,7 @@ +// build-pass + +trait X {} + +fn hello ! { loop {} } 1 }>>() {} + +fn main() {} From 0df6dfdc78624282b4193fc2290ba79d26ba6db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 1 Feb 2024 22:38:16 +0000 Subject: [PATCH 35/35] fix rebase --- tests/incremental/hashes/trait_defs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index 437b364e001ee..60faf3c47d69d 100644 --- a/tests/incremental/hashes/trait_defs.rs +++ b/tests/incremental/hashes/trait_defs.rs @@ -559,7 +559,7 @@ trait TraitAddBuiltinBoundToMethodTypeParameter { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddBuiltinBoundToMethodTypeParameter { #[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")]