From da25af2940f44f841f91ba038535e8e84c4893f3 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 17 Aug 2021 13:55:31 -0700 Subject: [PATCH 01/32] Make spans for tuple patterns in E0023 more precise As suggested in #86307. --- compiler/rustc_typeck/src/check/pat.rs | 6 ++- .../tuple_struct_destructure_fail.stderr | 24 +++++++---- src/test/ui/error-codes/E0023.stderr | 30 ++++++++----- src/test/ui/issues/issue-72574-2.stderr | 6 ++- .../match/match-pattern-field-mismatch.stderr | 6 ++- ...7-pat-tup-scrut-ty-diff-less-fields.stderr | 6 ++- src/test/ui/pattern/issue-74539.stderr | 6 ++- .../ui/pattern/pat-tuple-overfield.stderr | 12 ++++-- .../ui/pattern/pat-tuple-underfield.stderr | 42 ++++++++++++------- .../ui/pattern/pattern-error-continue.stderr | 6 ++- 10 files changed, 96 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index dae574bb7bf0f..2ef79c7686c51 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -990,10 +990,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let subpats_ending = pluralize!(subpats.len()); let fields_ending = pluralize!(fields.len()); + let fields_span = pat_span.trim_start(qpath.span()).unwrap_or(pat_span); let res_span = self.tcx.def_span(res.def_id()); let mut err = struct_span_err!( self.tcx.sess, - pat_span, + fields_span, E0023, "this pattern has {} field{}, but the corresponding {} has {} field{}", subpats.len(), @@ -1003,9 +1004,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fields_ending, ); err.span_label( - pat_span, + fields_span, format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len(),), ) + .span_label(qpath.span(), format!("this {}", res.descr())) .span_label(res_span, format!("{} defined here", res.descr())); // Identify the case `Some(x, y)` where the expected type is e.g. `Option<(T, U)>`. diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr index 0e92cc5c9f282..ec7d76f4fe523 100644 --- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr +++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr @@ -15,22 +15,26 @@ LL | Enum::SingleVariant(a, .., b, ..) = Enum::SingleVariant(0, 1); | previously used here error[E0023]: this pattern has 3 fields, but the corresponding tuple struct has 2 fields - --> $DIR/tuple_struct_destructure_fail.rs:30:5 + --> $DIR/tuple_struct_destructure_fail.rs:30:16 | LL | struct TupleStruct(S, T); | ------------------------------- tuple struct defined here ... LL | TupleStruct(a, a, b) = TupleStruct(1, 2); - | ^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3 + | -----------^^^^^^^^^ expected 2 fields, found 3 + | | + | this tuple struct error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields - --> $DIR/tuple_struct_destructure_fail.rs:32:5 + --> $DIR/tuple_struct_destructure_fail.rs:32:16 | LL | struct TupleStruct(S, T); | ------------------------------- tuple struct defined here ... LL | TupleStruct(_) = TupleStruct(1, 2); - | ^^^^^^^^^^^^^^ expected 2 fields, found 1 + | -----------^^^ expected 2 fields, found 1 + | | + | this tuple struct | help: use `_` to explicitly ignore each field | @@ -42,22 +46,26 @@ LL | TupleStruct(..) = TupleStruct(1, 2); | ~~ error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields - --> $DIR/tuple_struct_destructure_fail.rs:34:5 + --> $DIR/tuple_struct_destructure_fail.rs:34:24 | LL | SingleVariant(S, T) | ------------------- tuple variant defined here ... LL | Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3 + | -------------------^^^^^^^^^ expected 2 fields, found 3 + | | + | this tuple variant error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/tuple_struct_destructure_fail.rs:36:5 + --> $DIR/tuple_struct_destructure_fail.rs:36:24 | LL | SingleVariant(S, T) | ------------------- tuple variant defined here ... LL | Enum::SingleVariant(_) = Enum::SingleVariant(1, 2); - | ^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 1 + | -------------------^^^ expected 2 fields, found 1 + | | + | this tuple variant | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr index ec3aae2971410..ecc075b6fb4b5 100644 --- a/src/test/ui/error-codes/E0023.stderr +++ b/src/test/ui/error-codes/E0023.stderr @@ -1,11 +1,13 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/E0023.rs:11:9 + --> $DIR/E0023.rs:11:21 | LL | Apple(String, String), | --------------------- tuple variant defined here ... LL | Fruit::Apple(a) => {}, - | ^^^^^^^^^^^^^^^ expected 2 fields, found 1 + | ------------^^^ expected 2 fields, found 1 + | | + | this tuple variant | help: use `_` to explicitly ignore each field | @@ -13,31 +15,37 @@ LL | Fruit::Apple(a, _) => {}, | +++ error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields - --> $DIR/E0023.rs:12:9 + --> $DIR/E0023.rs:12:21 | LL | Apple(String, String), | --------------------- tuple variant defined here ... LL | Fruit::Apple(a, b, c) => {}, - | ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3 + | ------------^^^^^^^^^ expected 2 fields, found 3 + | | + | this tuple variant error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field - --> $DIR/E0023.rs:13:9 + --> $DIR/E0023.rs:13:20 | LL | Pear(u32), | --------- tuple variant defined here ... LL | Fruit::Pear(1, 2) => {}, - | ^^^^^^^^^^^^^^^^^ expected 1 field, found 2 + | -----------^^^^^^ expected 1 field, found 2 + | | + | this tuple variant error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field - --> $DIR/E0023.rs:14:9 + --> $DIR/E0023.rs:14:22 | LL | Orange((String, String)), | ------------------------ tuple variant defined here ... LL | Fruit::Orange(a, b) => {}, - | ^^^^^^^^^^^^^^^^^^^ expected 1 field, found 2 + | -------------^^^^^^ expected 1 field, found 2 + | | + | this tuple variant | help: missing parentheses | @@ -45,13 +53,15 @@ LL | Fruit::Orange((a, b)) => {}, | + + error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 1 field - --> $DIR/E0023.rs:15:9 + --> $DIR/E0023.rs:15:22 | LL | Banana(()), | ---------- tuple variant defined here ... LL | Fruit::Banana() => {}, - | ^^^^^^^^^^^^^^^ expected 1 field, found 0 + | -------------^^ expected 1 field, found 0 + | | + | this tuple variant | help: missing parentheses | diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr index 928fa58b17556..4c38d2c31ed68 100644 --- a/src/test/ui/issues/issue-72574-2.stderr +++ b/src/test/ui/issues/issue-72574-2.stderr @@ -19,13 +19,15 @@ LL | Binder(_a, _x @ ..) => {} = note: only allowed in tuple, tuple struct, and slice patterns error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields - --> $DIR/issue-72574-2.rs:6:9 + --> $DIR/issue-72574-2.rs:6:15 | LL | struct Binder(i32, i32, i32); | ----------------------------- tuple struct defined here ... LL | Binder(_a, _x @ ..) => {} - | ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2 + | ------^^^^^^^^^^^^^ expected 3 fields, found 2 + | | + | this tuple struct | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr index e34164ec0db24..776cdfc7083bb 100644 --- a/src/test/ui/match/match-pattern-field-mismatch.stderr +++ b/src/test/ui/match/match-pattern-field-mismatch.stderr @@ -1,11 +1,13 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields - --> $DIR/match-pattern-field-mismatch.rs:10:11 + --> $DIR/match-pattern-field-mismatch.rs:10:21 | LL | Rgb(usize, usize, usize), | ------------------------ tuple variant defined here ... LL | Color::Rgb(_, _) => { } - | ^^^^^^^^^^^^^^^^ expected 3 fields, found 2 + | ----------^^^^^^ expected 3 fields, found 2 + | | + | this tuple variant | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr index 7f5da8f3c2dcc..ea5f970d1d659 100644 --- a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr +++ b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr @@ -10,13 +10,15 @@ LL | let P() = U {}; found struct `P<_>` error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 1 field - --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9 + --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:10 | LL | struct P(T); // 1 type parameter wanted | --------------- tuple struct defined here ... LL | let P() = U {}; - | ^^^ expected 1 field, found 0 + | -^^ expected 1 field, found 0 + | | + | this tuple struct | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/issue-74539.stderr b/src/test/ui/pattern/issue-74539.stderr index 7d998af7fb388..87c3842d28f4e 100644 --- a/src/test/ui/pattern/issue-74539.stderr +++ b/src/test/ui/pattern/issue-74539.stderr @@ -19,13 +19,15 @@ LL | E::A(x @ ..) => { = note: only allowed in tuple, tuple struct, and slice patterns error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/issue-74539.rs:8:9 + --> $DIR/issue-74539.rs:8:13 | LL | A(u8, u8), | --------- tuple variant defined here ... LL | E::A(x @ ..) => { - | ^^^^^^^^^^^^ expected 2 fields, found 1 + | ----^^^^^^^^ expected 2 fields, found 1 + | | + | this tuple variant | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr index 45b6fd1b4d445..e0386d9cd4ffc 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.stderr +++ b/src/test/ui/pattern/pat-tuple-overfield.stderr @@ -22,22 +22,26 @@ LL | (1, 2, .., 3, 4) => {} found tuple `(_, _, _, _)` error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-overfield.rs:10:9 + --> $DIR/pat-tuple-overfield.rs:10:10 | LL | struct S(u8, u8, u8); | --------------------- tuple struct defined here ... LL | S(1, 2, 3, 4) => {} - | ^^^^^^^^^^^^^ expected 3 fields, found 4 + | -^^^^^^^^^^^^ expected 3 fields, found 4 + | | + | this tuple struct error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-overfield.rs:12:9 + --> $DIR/pat-tuple-overfield.rs:12:10 | LL | struct S(u8, u8, u8); | --------------------- tuple struct defined here ... LL | S(1, 2, .., 3, 4) => {} - | ^^^^^^^^^^^^^^^^^ expected 3 fields, found 4 + | -^^^^^^^^^^^^^^^^ expected 3 fields, found 4 + | | + | this tuple struct error: aborting due to 4 previous errors diff --git a/src/test/ui/pattern/pat-tuple-underfield.stderr b/src/test/ui/pattern/pat-tuple-underfield.stderr index 2fbcb6d67ba36..4cc20a4ac0ef7 100644 --- a/src/test/ui/pattern/pat-tuple-underfield.stderr +++ b/src/test/ui/pattern/pat-tuple-underfield.stderr @@ -8,13 +8,15 @@ LL | E::S => {} | ^^^^ help: use the tuple variant pattern syntax instead: `E::S(_, _)` error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields - --> $DIR/pat-tuple-underfield.rs:9:9 + --> $DIR/pat-tuple-underfield.rs:9:10 | LL | struct S(i32, f32); | ------------------- tuple struct defined here ... LL | S(x) => {} - | ^^^^ expected 2 fields, found 1 + | -^^^ expected 2 fields, found 1 + | | + | this tuple struct | help: use `_` to explicitly ignore each field | @@ -22,13 +24,15 @@ LL | S(x, _) => {} | +++ error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields - --> $DIR/pat-tuple-underfield.rs:14:9 + --> $DIR/pat-tuple-underfield.rs:14:10 | LL | struct S(i32, f32); | ------------------- tuple struct defined here ... LL | S(_) => {} - | ^^^^ expected 2 fields, found 1 + | -^^^ expected 2 fields, found 1 + | | + | this tuple struct | help: use `_` to explicitly ignore each field | @@ -40,13 +44,15 @@ LL | S(..) => {} | ~~ error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 2 fields - --> $DIR/pat-tuple-underfield.rs:20:9 + --> $DIR/pat-tuple-underfield.rs:20:10 | LL | struct S(i32, f32); | ------------------- tuple struct defined here ... LL | S() => {} - | ^^^ expected 2 fields, found 0 + | -^^ expected 2 fields, found 0 + | | + | this tuple struct | help: use `_` to explicitly ignore each field | @@ -58,13 +64,15 @@ LL | S(..) => {} | ++ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/pat-tuple-underfield.rs:27:9 + --> $DIR/pat-tuple-underfield.rs:27:13 | LL | S(i32, f32), | ----------- tuple variant defined here ... LL | E::S(x) => {} - | ^^^^^^^ expected 2 fields, found 1 + | ----^^^ expected 2 fields, found 1 + | | + | this tuple variant | help: use `_` to explicitly ignore each field | @@ -72,13 +80,15 @@ LL | E::S(x, _) => {} | +++ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/pat-tuple-underfield.rs:32:9 + --> $DIR/pat-tuple-underfield.rs:32:13 | LL | S(i32, f32), | ----------- tuple variant defined here ... LL | E::S(_) => {} - | ^^^^^^^ expected 2 fields, found 1 + | ----^^^ expected 2 fields, found 1 + | | + | this tuple variant | help: use `_` to explicitly ignore each field | @@ -90,13 +100,15 @@ LL | E::S(..) => {} | ~~ error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 2 fields - --> $DIR/pat-tuple-underfield.rs:38:9 + --> $DIR/pat-tuple-underfield.rs:38:13 | LL | S(i32, f32), | ----------- tuple variant defined here ... LL | E::S() => {} - | ^^^^^^ expected 2 fields, found 0 + | ----^^ expected 2 fields, found 0 + | | + | this tuple variant | help: use `_` to explicitly ignore each field | @@ -108,13 +120,15 @@ LL | E::S(..) => {} | ++ error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 4 fields - --> $DIR/pat-tuple-underfield.rs:50:9 + --> $DIR/pat-tuple-underfield.rs:50:15 | LL | struct Point4(i32, i32, i32, i32); | ---------------------------------- tuple struct defined here ... LL | Point4( a , _ ) => {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 4 fields, found 2 + | ------^^^^^^^^^^^^^^^^^^^^ expected 4 fields, found 2 + | | + | this tuple struct | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr index 3f28ffed29162..216c3ca47d393 100644 --- a/src/test/ui/pattern/pattern-error-continue.stderr +++ b/src/test/ui/pattern/pattern-error-continue.stderr @@ -26,13 +26,15 @@ LL | A::B(_) => (), | ~ error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields - --> $DIR/pattern-error-continue.rs:17:9 + --> $DIR/pattern-error-continue.rs:17:13 | LL | B(isize, isize), | --------------- tuple variant defined here ... LL | A::B(_, _, _) => (), - | ^^^^^^^^^^^^^ expected 2 fields, found 3 + | ----^^^^^^^^^ expected 2 fields, found 3 + | | + | this tuple variant error[E0308]: mismatched types --> $DIR/pattern-error-continue.rs:22:9 From f1e860757e9494c82450c100a9ce5240858b537b Mon Sep 17 00:00:00 2001 From: Kornel Date: Sat, 21 Aug 2021 23:40:02 +0100 Subject: [PATCH 02/32] Don't stabilize creation of TryReserveError instances --- library/alloc/src/collections/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs index 0d442011921ba..4e31df8b4b8c2 100644 --- a/library/alloc/src/collections/mod.rs +++ b/library/alloc/src/collections/mod.rs @@ -117,12 +117,12 @@ impl From for TryReserveError { } } -#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] -impl From for TryReserveError { +#[unstable(feature = "try_reserve_kind", reason = "new API", issue = "48043")] +impl From for TryReserveErrorKind { /// Always evaluates to [`TryReserveErrorKind::CapacityOverflow`]. #[inline] fn from(_: LayoutError) -> Self { - TryReserveErrorKind::CapacityOverflow.into() + TryReserveErrorKind::CapacityOverflow } } From d0b482a27c1a347eac366bde82340e527c6cecf8 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 18 Aug 2021 16:13:25 -0700 Subject: [PATCH 03/32] Add more tuple pattern too many fields test cases --- src/test/ui/pattern/pat-tuple-overfield.rs | 42 ++++ .../ui/pattern/pat-tuple-overfield.stderr | 222 +++++++++++++++++- 2 files changed, 258 insertions(+), 6 deletions(-) diff --git a/src/test/ui/pattern/pat-tuple-overfield.rs b/src/test/ui/pattern/pat-tuple-overfield.rs index 46a5e15ffa52c..dd0548a088c72 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.rs +++ b/src/test/ui/pattern/pat-tuple-overfield.rs @@ -1,4 +1,18 @@ struct S(u8, u8, u8); +struct M( + u8, + u8, + u8, + u8, + u8, +); + +struct Z0; +struct Z1(); +enum E1 { + Z0, + Z1(), +} fn main() { match (1, 2, 3) { @@ -13,4 +27,32 @@ fn main() { //~^ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields _ => {} } + match M(1, 2, 3, 4, 5) { + M(1, 2, 3, 4, 5, 6) => {} + //~^ ERROR this pattern has 6 fields, but the corresponding tuple struct has 5 fields + } + match Z0 { + Z0 => {} + Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0` + Z0(_) => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0` + Z0(_, _) => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0` + } + match Z1() { + Z1 => {} //~ ERROR match bindings cannot shadow tuple structs + Z1() => {} + Z1(_) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 0 fields + Z1(_, _) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 0 fields + } + match E1::Z0 { + E1::Z0 => {} + E1::Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0` + E1::Z0(_) => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0` + E1::Z0(_, _) => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0` + } + match E1::Z1() { + E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1` + E1::Z1() => {} + E1::Z1(_) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 0 fields + E1::Z1(_, _) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 0 fields + } } diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr index e0386d9cd4ffc..cc4ca4326eccd 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.stderr +++ b/src/test/ui/pattern/pat-tuple-overfield.stderr @@ -1,5 +1,154 @@ +error[E0530]: match bindings cannot shadow tuple structs + --> $DIR/pat-tuple-overfield.rs:43:9 + | +LL | struct Z1(); + | ------------ the tuple struct `Z1` is defined here +... +LL | Z1 => {} + | ^^ cannot be named the same as a tuple struct + +error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` + --> $DIR/pat-tuple-overfield.rs:38:9 + | +LL | struct Z0; + | ---------- `Z0` defined here +LL | struct Z1(); + | ------------ similarly named tuple struct `Z1` defined here +... +LL | Z0() => {} + | ^^^^ + | +help: use this syntax instead + | +LL | Z0 => {} + | ~~ +help: a tuple struct with a similar name exists + | +LL | Z1() => {} + | ~~ + +error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` + --> $DIR/pat-tuple-overfield.rs:39:9 + | +LL | struct Z0; + | ---------- `Z0` defined here +LL | struct Z1(); + | ------------ similarly named tuple struct `Z1` defined here +... +LL | Z0(_) => {} + | ^^^^^ + | +help: use this syntax instead + | +LL | Z0 => {} + | ~~ +help: a tuple struct with a similar name exists + | +LL | Z1(_) => {} + | ~~ + +error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` + --> $DIR/pat-tuple-overfield.rs:40:9 + | +LL | struct Z0; + | ---------- `Z0` defined here +LL | struct Z1(); + | ------------ similarly named tuple struct `Z1` defined here +... +LL | Z0(_, _) => {} + | ^^^^^^^^ + | +help: use this syntax instead + | +LL | Z0 => {} + | ~~ +help: a tuple struct with a similar name exists + | +LL | Z1(_, _) => {} + | ~~ + +error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` + --> $DIR/pat-tuple-overfield.rs:50:9 + | +LL | Z0, + | -- `E1::Z0` defined here +LL | Z1(), + | ---- similarly named tuple variant `Z1` defined here +... +LL | E1::Z0() => {} + | ^^^^^^^^ + | +help: use this syntax instead + | +LL | E1::Z0 => {} + | ~~~~~~ +help: a tuple variant with a similar name exists + | +LL | E1::Z1() => {} + | ~~ + +error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` + --> $DIR/pat-tuple-overfield.rs:51:9 + | +LL | Z0, + | -- `E1::Z0` defined here +LL | Z1(), + | ---- similarly named tuple variant `Z1` defined here +... +LL | E1::Z0(_) => {} + | ^^^^^^^^^ + | +help: use this syntax instead + | +LL | E1::Z0 => {} + | ~~~~~~ +help: a tuple variant with a similar name exists + | +LL | E1::Z1(_) => {} + | ~~ + +error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` + --> $DIR/pat-tuple-overfield.rs:52:9 + | +LL | Z0, + | -- `E1::Z0` defined here +LL | Z1(), + | ---- similarly named tuple variant `Z1` defined here +... +LL | E1::Z0(_, _) => {} + | ^^^^^^^^^^^^ + | +help: use this syntax instead + | +LL | E1::Z0 => {} + | ~~~~~~ +help: a tuple variant with a similar name exists + | +LL | E1::Z1(_, _) => {} + | ~~ + +error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1` + --> $DIR/pat-tuple-overfield.rs:55:9 + | +LL | Z0, + | -- similarly named unit variant `Z0` defined here +LL | Z1(), + | ---- `E1::Z1` defined here +... +LL | E1::Z1 => {} + | ^^^^^^ + | +help: use the tuple variant pattern syntax instead + | +LL | E1::Z1() => {} + | ~~~~~~~~ +help: a unit variant with a similar name exists + | +LL | E1::Z0 => {} + | ~~ + error[E0308]: mismatched types - --> $DIR/pat-tuple-overfield.rs:5:9 + --> $DIR/pat-tuple-overfield.rs:21:9 | LL | match (1, 2, 3) { | --------- this expression has type `({integer}, {integer}, {integer})` @@ -10,7 +159,7 @@ LL | (1, 2, 3, 4) => {} found tuple `(_, _, _, _)` error[E0308]: mismatched types - --> $DIR/pat-tuple-overfield.rs:6:9 + --> $DIR/pat-tuple-overfield.rs:22:9 | LL | match (1, 2, 3) { | --------- this expression has type `({integer}, {integer}, {integer})` @@ -22,7 +171,7 @@ LL | (1, 2, .., 3, 4) => {} found tuple `(_, _, _, _)` error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-overfield.rs:10:10 + --> $DIR/pat-tuple-overfield.rs:26:10 | LL | struct S(u8, u8, u8); | --------------------- tuple struct defined here @@ -33,7 +182,7 @@ LL | S(1, 2, 3, 4) => {} | this tuple struct error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-overfield.rs:12:10 + --> $DIR/pat-tuple-overfield.rs:28:10 | LL | struct S(u8, u8, u8); | --------------------- tuple struct defined here @@ -43,7 +192,68 @@ LL | S(1, 2, .., 3, 4) => {} | | | this tuple struct -error: aborting due to 4 previous errors +error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields + --> $DIR/pat-tuple-overfield.rs:33:10 + | +LL | / struct M( +LL | | u8, +LL | | u8, +LL | | u8, +LL | | u8, +LL | | u8, +LL | | ); + | |__- tuple struct defined here +... +LL | M(1, 2, 3, 4, 5, 6) => {} + | -^^^^^^^^^^^^^^^^^^ expected 5 fields, found 6 + | | + | this tuple struct + +error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields + --> $DIR/pat-tuple-overfield.rs:45:11 + | +LL | struct Z1(); + | ------------ tuple struct defined here +... +LL | Z1(_) => {} + | --^^^ expected 0 fields, found 1 + | | + | this tuple struct + +error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 0 fields + --> $DIR/pat-tuple-overfield.rs:46:11 + | +LL | struct Z1(); + | ------------ tuple struct defined here +... +LL | Z1(_, _) => {} + | --^^^^^^ expected 0 fields, found 2 + | | + | this tuple struct + +error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields + --> $DIR/pat-tuple-overfield.rs:57:15 + | +LL | Z1(), + | ---- tuple variant defined here +... +LL | E1::Z1(_) => {} + | ------^^^ expected 0 fields, found 1 + | | + | this tuple variant + +error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 0 fields + --> $DIR/pat-tuple-overfield.rs:58:15 + | +LL | Z1(), + | ---- tuple variant defined here +... +LL | E1::Z1(_, _) => {} + | ------^^^^^^ expected 0 fields, found 2 + | | + | this tuple variant + +error: aborting due to 17 previous errors -Some errors have detailed explanations: E0023, E0308. +Some errors have detailed explanations: E0023, E0308, E0530, E0532. For more information about an error, try `rustc --explain E0023`. From 0fa3b4f940b4705dc5a1089e917f521b093fd0bc Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 18 Aug 2021 16:13:52 -0700 Subject: [PATCH 04/32] Make E0023 spans even more precise --- compiler/rustc_ty_utils/src/ty.rs | 13 +++- compiler/rustc_typeck/src/check/pat.rs | 39 ++++++++-- .../tuple_struct_destructure_fail.stderr | 32 +++----- src/test/ui/error-codes/E0023.stderr | 36 ++++----- src/test/ui/issues/issue-72574-2.stderr | 8 +- .../match/match-pattern-field-mismatch.stderr | 8 +- ...7-pat-tup-scrut-ty-diff-less-fields.stderr | 4 +- src/test/ui/pattern/issue-74539.stderr | 8 +- .../ui/pattern/pat-tuple-overfield.stderr | 78 ++++++++----------- .../ui/pattern/pat-tuple-underfield.stderr | 48 ++++-------- .../ui/pattern/pattern-error-continue.stderr | 8 +- 11 files changed, 132 insertions(+), 150 deletions(-) diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index b0d644ae028ce..7a6ace070dee5 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -223,7 +223,18 @@ fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems<'_> { } fn def_ident_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - tcx.hir().get_if_local(def_id).and_then(|node| node.ident()).map(|ident| ident.span) + tcx.hir() + .get_if_local(def_id) + .and_then(|node| match node { + // A `Ctor` doesn't have an identifier itself, but its parent + // struct/variant does. Compare with `hir::Map::opt_span`. + hir::Node::Ctor(ctor) => ctor + .ctor_hir_id() + .and_then(|ctor_id| tcx.hir().find(tcx.hir().get_parent_node(ctor_id))) + .and_then(|parent| parent.ident()), + _ => node.ident(), + }) + .map(|ident| ident.span) } /// If the given `DefId` describes an item belonging to a trait, diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 2ef79c7686c51..341385731e7d2 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -15,7 +15,7 @@ use rustc_span::hygiene::DesugaringKind; use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::source_map::{Span, Spanned}; use rustc_span::symbol::Ident; -use rustc_span::{BytePos, DUMMY_SP}; +use rustc_span::{BytePos, MultiSpan, DUMMY_SP}; use rustc_trait_selection::autoderef::Autoderef; use rustc_trait_selection::traits::{ObligationCause, Pattern}; use ty::VariantDef; @@ -990,11 +990,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let subpats_ending = pluralize!(subpats.len()); let fields_ending = pluralize!(fields.len()); - let fields_span = pat_span.trim_start(qpath.span()).unwrap_or(pat_span); + + let subpat_spans = if subpats.is_empty() { + vec![pat_span.trim_start(qpath.span()).unwrap_or(pat_span)] + } else { + subpats.iter().map(|p| p.span).collect() + }; + let last_subpat_span = *subpat_spans.last().unwrap(); let res_span = self.tcx.def_span(res.def_id()); + let def_ident_span = self.tcx.def_ident_span(res.def_id()).unwrap_or(res_span); + let field_def_spans = if fields.is_empty() { + vec![res_span.trim_start(def_ident_span).unwrap_or(res_span)] + } else { + fields.iter().map(|f| f.ident.span).collect() + }; + let last_field_def_span = *field_def_spans.last().unwrap(); + let mut err = struct_span_err!( self.tcx.sess, - fields_span, + MultiSpan::from_spans(subpat_spans.clone()), E0023, "this pattern has {} field{}, but the corresponding {} has {} field{}", subpats.len(), @@ -1004,11 +1018,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fields_ending, ); err.span_label( - fields_span, - format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len(),), - ) - .span_label(qpath.span(), format!("this {}", res.descr())) - .span_label(res_span, format!("{} defined here", res.descr())); + last_subpat_span, + &format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len()), + ); + err.span_label(qpath.span(), ""); + if self.tcx.sess.source_map().is_multiline(def_ident_span.between(field_def_spans[0])) { + err.span_label(def_ident_span, format!("{} defined here", res.descr())); + } + for span in &field_def_spans[..field_def_spans.len() - 1] { + err.span_label(*span, ""); + } + err.span_label( + last_field_def_span, + &format!("{} has {} field{}", res.descr(), fields.len(), fields_ending), + ); // Identify the case `Some(x, y)` where the expected type is e.g. `Option<(T, U)>`. // More generally, the expected type wants a tuple variant with one field of an diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr index ec7d76f4fe523..9a47ddf047991 100644 --- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr +++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr @@ -15,26 +15,22 @@ LL | Enum::SingleVariant(a, .., b, ..) = Enum::SingleVariant(0, 1); | previously used here error[E0023]: this pattern has 3 fields, but the corresponding tuple struct has 2 fields - --> $DIR/tuple_struct_destructure_fail.rs:30:16 + --> $DIR/tuple_struct_destructure_fail.rs:30:17 | LL | struct TupleStruct(S, T); - | ------------------------------- tuple struct defined here + | - - tuple struct has 2 fields ... LL | TupleStruct(a, a, b) = TupleStruct(1, 2); - | -----------^^^^^^^^^ expected 2 fields, found 3 - | | - | this tuple struct + | ----------- ^ ^ ^ expected 2 fields, found 3 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields - --> $DIR/tuple_struct_destructure_fail.rs:32:16 + --> $DIR/tuple_struct_destructure_fail.rs:32:17 | LL | struct TupleStruct(S, T); - | ------------------------------- tuple struct defined here + | - - tuple struct has 2 fields ... LL | TupleStruct(_) = TupleStruct(1, 2); - | -----------^^^ expected 2 fields, found 1 - | | - | this tuple struct + | ----------- ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -46,26 +42,22 @@ LL | TupleStruct(..) = TupleStruct(1, 2); | ~~ error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields - --> $DIR/tuple_struct_destructure_fail.rs:34:24 + --> $DIR/tuple_struct_destructure_fail.rs:34:25 | LL | SingleVariant(S, T) - | ------------------- tuple variant defined here + | - - tuple variant has 2 fields ... LL | Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2); - | -------------------^^^^^^^^^ expected 2 fields, found 3 - | | - | this tuple variant + | ------------------- ^ ^ ^ expected 2 fields, found 3 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/tuple_struct_destructure_fail.rs:36:24 + --> $DIR/tuple_struct_destructure_fail.rs:36:25 | LL | SingleVariant(S, T) - | ------------------- tuple variant defined here + | - - tuple variant has 2 fields ... LL | Enum::SingleVariant(_) = Enum::SingleVariant(1, 2); - | -------------------^^^ expected 2 fields, found 1 - | | - | this tuple variant + | ------------------- ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr index ecc075b6fb4b5..85e1b2cb4ceef 100644 --- a/src/test/ui/error-codes/E0023.stderr +++ b/src/test/ui/error-codes/E0023.stderr @@ -1,13 +1,11 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/E0023.rs:11:21 + --> $DIR/E0023.rs:11:22 | LL | Apple(String, String), - | --------------------- tuple variant defined here + | ------ ------ tuple variant has 2 fields ... LL | Fruit::Apple(a) => {}, - | ------------^^^ expected 2 fields, found 1 - | | - | this tuple variant + | ------------ ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -15,37 +13,31 @@ LL | Fruit::Apple(a, _) => {}, | +++ error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields - --> $DIR/E0023.rs:12:21 + --> $DIR/E0023.rs:12:22 | LL | Apple(String, String), - | --------------------- tuple variant defined here + | ------ ------ tuple variant has 2 fields ... LL | Fruit::Apple(a, b, c) => {}, - | ------------^^^^^^^^^ expected 2 fields, found 3 - | | - | this tuple variant + | ------------ ^ ^ ^ expected 2 fields, found 3 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field - --> $DIR/E0023.rs:13:20 + --> $DIR/E0023.rs:13:21 | LL | Pear(u32), - | --------- tuple variant defined here + | --- tuple variant has 1 field ... LL | Fruit::Pear(1, 2) => {}, - | -----------^^^^^^ expected 1 field, found 2 - | | - | this tuple variant + | ----------- ^ ^ expected 1 field, found 2 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field - --> $DIR/E0023.rs:14:22 + --> $DIR/E0023.rs:14:23 | LL | Orange((String, String)), - | ------------------------ tuple variant defined here + | ---------------- tuple variant has 1 field ... LL | Fruit::Orange(a, b) => {}, - | -------------^^^^^^ expected 1 field, found 2 - | | - | this tuple variant + | ------------- ^ ^ expected 1 field, found 2 | help: missing parentheses | @@ -56,12 +48,10 @@ error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has --> $DIR/E0023.rs:15:22 | LL | Banana(()), - | ---------- tuple variant defined here + | -- tuple variant has 1 field ... LL | Fruit::Banana() => {}, | -------------^^ expected 1 field, found 0 - | | - | this tuple variant | help: missing parentheses | diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr index 4c38d2c31ed68..3f8ff4f0bacd5 100644 --- a/src/test/ui/issues/issue-72574-2.stderr +++ b/src/test/ui/issues/issue-72574-2.stderr @@ -19,15 +19,13 @@ LL | Binder(_a, _x @ ..) => {} = note: only allowed in tuple, tuple struct, and slice patterns error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields - --> $DIR/issue-72574-2.rs:6:15 + --> $DIR/issue-72574-2.rs:6:16 | LL | struct Binder(i32, i32, i32); - | ----------------------------- tuple struct defined here + | --- --- --- tuple struct has 3 fields ... LL | Binder(_a, _x @ ..) => {} - | ------^^^^^^^^^^^^^ expected 3 fields, found 2 - | | - | this tuple struct + | ------ ^^ ^^^^^^^ expected 3 fields, found 2 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr index 776cdfc7083bb..01d7cf0d054c9 100644 --- a/src/test/ui/match/match-pattern-field-mismatch.stderr +++ b/src/test/ui/match/match-pattern-field-mismatch.stderr @@ -1,13 +1,11 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields - --> $DIR/match-pattern-field-mismatch.rs:10:21 + --> $DIR/match-pattern-field-mismatch.rs:10:22 | LL | Rgb(usize, usize, usize), - | ------------------------ tuple variant defined here + | ----- ----- ----- tuple variant has 3 fields ... LL | Color::Rgb(_, _) => { } - | ----------^^^^^^ expected 3 fields, found 2 - | | - | this tuple variant + | ---------- ^ ^ expected 3 fields, found 2 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr index ea5f970d1d659..c87b70625b40e 100644 --- a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr +++ b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr @@ -13,12 +13,10 @@ error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:10 | LL | struct P(T); // 1 type parameter wanted - | --------------- tuple struct defined here + | - tuple struct has 1 field ... LL | let P() = U {}; | -^^ expected 1 field, found 0 - | | - | this tuple struct | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/issue-74539.stderr b/src/test/ui/pattern/issue-74539.stderr index 87c3842d28f4e..d7cbcf2cfa109 100644 --- a/src/test/ui/pattern/issue-74539.stderr +++ b/src/test/ui/pattern/issue-74539.stderr @@ -19,15 +19,13 @@ LL | E::A(x @ ..) => { = note: only allowed in tuple, tuple struct, and slice patterns error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/issue-74539.rs:8:13 + --> $DIR/issue-74539.rs:8:14 | LL | A(u8, u8), - | --------- tuple variant defined here + | -- -- tuple variant has 2 fields ... LL | E::A(x @ ..) => { - | ----^^^^^^^^ expected 2 fields, found 1 - | | - | this tuple variant + | ---- ^^^^^^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr index cc4ca4326eccd..1df9c1c11b8a5 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.stderr +++ b/src/test/ui/pattern/pat-tuple-overfield.stderr @@ -171,87 +171,77 @@ LL | (1, 2, .., 3, 4) => {} found tuple `(_, _, _, _)` error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-overfield.rs:26:10 + --> $DIR/pat-tuple-overfield.rs:26:11 | LL | struct S(u8, u8, u8); - | --------------------- tuple struct defined here + | -- -- -- tuple struct has 3 fields ... LL | S(1, 2, 3, 4) => {} - | -^^^^^^^^^^^^ expected 3 fields, found 4 - | | - | this tuple struct + | - ^ ^ ^ ^ expected 3 fields, found 4 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-overfield.rs:28:10 + --> $DIR/pat-tuple-overfield.rs:28:11 | LL | struct S(u8, u8, u8); - | --------------------- tuple struct defined here + | -- -- -- tuple struct has 3 fields ... LL | S(1, 2, .., 3, 4) => {} - | -^^^^^^^^^^^^^^^^ expected 3 fields, found 4 - | | - | this tuple struct + | - ^ ^ ^ ^ expected 3 fields, found 4 error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields - --> $DIR/pat-tuple-overfield.rs:33:10 - | -LL | / struct M( -LL | | u8, -LL | | u8, -LL | | u8, -LL | | u8, -LL | | u8, -LL | | ); - | |__- tuple struct defined here + --> $DIR/pat-tuple-overfield.rs:33:11 + | +LL | struct M( + | - tuple struct defined here +LL | u8, + | -- +LL | u8, + | -- +LL | u8, + | -- +LL | u8, + | -- +LL | u8, + | -- tuple struct has 5 fields ... -LL | M(1, 2, 3, 4, 5, 6) => {} - | -^^^^^^^^^^^^^^^^^^ expected 5 fields, found 6 - | | - | this tuple struct +LL | M(1, 2, 3, 4, 5, 6) => {} + | - ^ ^ ^ ^ ^ ^ expected 5 fields, found 6 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields - --> $DIR/pat-tuple-overfield.rs:45:11 + --> $DIR/pat-tuple-overfield.rs:45:12 | LL | struct Z1(); - | ------------ tuple struct defined here + | --- tuple struct has 0 fields ... LL | Z1(_) => {} - | --^^^ expected 0 fields, found 1 - | | - | this tuple struct + | -- ^ expected 0 fields, found 1 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 0 fields - --> $DIR/pat-tuple-overfield.rs:46:11 + --> $DIR/pat-tuple-overfield.rs:46:12 | LL | struct Z1(); - | ------------ tuple struct defined here + | --- tuple struct has 0 fields ... LL | Z1(_, _) => {} - | --^^^^^^ expected 0 fields, found 2 - | | - | this tuple struct + | -- ^ ^ expected 0 fields, found 2 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields - --> $DIR/pat-tuple-overfield.rs:57:15 + --> $DIR/pat-tuple-overfield.rs:57:16 | LL | Z1(), - | ---- tuple variant defined here + | -- tuple variant has 0 fields ... LL | E1::Z1(_) => {} - | ------^^^ expected 0 fields, found 1 - | | - | this tuple variant + | ------ ^ expected 0 fields, found 1 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 0 fields - --> $DIR/pat-tuple-overfield.rs:58:15 + --> $DIR/pat-tuple-overfield.rs:58:16 | LL | Z1(), - | ---- tuple variant defined here + | -- tuple variant has 0 fields ... LL | E1::Z1(_, _) => {} - | ------^^^^^^ expected 0 fields, found 2 - | | - | this tuple variant + | ------ ^ ^ expected 0 fields, found 2 error: aborting due to 17 previous errors diff --git a/src/test/ui/pattern/pat-tuple-underfield.stderr b/src/test/ui/pattern/pat-tuple-underfield.stderr index 4cc20a4ac0ef7..4c21ad0be3eb4 100644 --- a/src/test/ui/pattern/pat-tuple-underfield.stderr +++ b/src/test/ui/pattern/pat-tuple-underfield.stderr @@ -8,15 +8,13 @@ LL | E::S => {} | ^^^^ help: use the tuple variant pattern syntax instead: `E::S(_, _)` error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields - --> $DIR/pat-tuple-underfield.rs:9:10 + --> $DIR/pat-tuple-underfield.rs:9:11 | LL | struct S(i32, f32); - | ------------------- tuple struct defined here + | --- --- tuple struct has 2 fields ... LL | S(x) => {} - | -^^^ expected 2 fields, found 1 - | | - | this tuple struct + | - ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -24,15 +22,13 @@ LL | S(x, _) => {} | +++ error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields - --> $DIR/pat-tuple-underfield.rs:14:10 + --> $DIR/pat-tuple-underfield.rs:14:11 | LL | struct S(i32, f32); - | ------------------- tuple struct defined here + | --- --- tuple struct has 2 fields ... LL | S(_) => {} - | -^^^ expected 2 fields, found 1 - | | - | this tuple struct + | - ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -47,12 +43,10 @@ error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has --> $DIR/pat-tuple-underfield.rs:20:10 | LL | struct S(i32, f32); - | ------------------- tuple struct defined here + | --- --- tuple struct has 2 fields ... LL | S() => {} | -^^ expected 2 fields, found 0 - | | - | this tuple struct | help: use `_` to explicitly ignore each field | @@ -64,15 +58,13 @@ LL | S(..) => {} | ++ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/pat-tuple-underfield.rs:27:13 + --> $DIR/pat-tuple-underfield.rs:27:14 | LL | S(i32, f32), - | ----------- tuple variant defined here + | --- --- tuple variant has 2 fields ... LL | E::S(x) => {} - | ----^^^ expected 2 fields, found 1 - | | - | this tuple variant + | ---- ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -80,15 +72,13 @@ LL | E::S(x, _) => {} | +++ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/pat-tuple-underfield.rs:32:13 + --> $DIR/pat-tuple-underfield.rs:32:14 | LL | S(i32, f32), - | ----------- tuple variant defined here + | --- --- tuple variant has 2 fields ... LL | E::S(_) => {} - | ----^^^ expected 2 fields, found 1 - | | - | this tuple variant + | ---- ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -103,12 +93,10 @@ error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has --> $DIR/pat-tuple-underfield.rs:38:13 | LL | S(i32, f32), - | ----------- tuple variant defined here + | --- --- tuple variant has 2 fields ... LL | E::S() => {} | ----^^ expected 2 fields, found 0 - | | - | this tuple variant | help: use `_` to explicitly ignore each field | @@ -120,15 +108,13 @@ LL | E::S(..) => {} | ++ error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 4 fields - --> $DIR/pat-tuple-underfield.rs:50:15 + --> $DIR/pat-tuple-underfield.rs:50:19 | LL | struct Point4(i32, i32, i32, i32); - | ---------------------------------- tuple struct defined here + | --- --- --- --- tuple struct has 4 fields ... LL | Point4( a , _ ) => {} - | ------^^^^^^^^^^^^^^^^^^^^ expected 4 fields, found 2 - | | - | this tuple struct + | ------ ^ ^ expected 4 fields, found 2 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr index 216c3ca47d393..efc6723e9ef8e 100644 --- a/src/test/ui/pattern/pattern-error-continue.stderr +++ b/src/test/ui/pattern/pattern-error-continue.stderr @@ -26,15 +26,13 @@ LL | A::B(_) => (), | ~ error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields - --> $DIR/pattern-error-continue.rs:17:13 + --> $DIR/pattern-error-continue.rs:17:14 | LL | B(isize, isize), - | --------------- tuple variant defined here + | ----- ----- tuple variant has 2 fields ... LL | A::B(_, _, _) => (), - | ----^^^^^^^^^ expected 2 fields, found 3 - | | - | this tuple variant + | ---- ^ ^ ^ expected 2 fields, found 3 error[E0308]: mismatched types --> $DIR/pattern-error-continue.rs:22:9 From 02ed23c0318da7f1125f01b5437ae9e809587f0c Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 18 Aug 2021 16:09:52 -0700 Subject: [PATCH 05/32] Use an exhaustive match in `Node::ident()` and add docs This should cause a compiler error in the future if more variants are added without `Node::ident()` being updated. --- compiler/rustc_hir/src/hir.rs | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4e233ed14577d..dd5dfe978a477 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3182,6 +3182,20 @@ pub enum Node<'hir> { } impl<'hir> Node<'hir> { + /// Get the identifier of this `Node`, if applicable. + /// + /// # Edge cases + /// + /// Calling `.ident()` on a [`Node::Ctor`] will return `None` + /// because `Ctor`s do not have identifiers themselves. + /// Instead, call `.ident()` on the parent struct/variant, like so: + /// + /// ```ignore (illustrative) + /// ctor + /// .ctor_hir_id() + /// .and_then(|ctor_id| tcx.hir().find(tcx.hir().get_parent_node(ctor_id))) + /// .and_then(|parent| parent.ident()) + /// ``` pub fn ident(&self) -> Option { match self { Node::TraitItem(TraitItem { ident, .. }) @@ -3190,8 +3204,25 @@ impl<'hir> Node<'hir> { | Node::Field(FieldDef { ident, .. }) | Node::Variant(Variant { ident, .. }) | Node::MacroDef(MacroDef { ident, .. }) - | Node::Item(Item { ident, .. }) => Some(*ident), - _ => None, + | Node::Item(Item { ident, .. }) + | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident), + Node::Lifetime(lt) => Some(lt.name.ident()), + Node::GenericParam(p) => Some(p.name.ident()), + Node::Param(..) + | Node::AnonConst(..) + | Node::Expr(..) + | Node::Stmt(..) + | Node::Block(..) + | Node::Ctor(..) + | Node::Pat(..) + | Node::Binding(..) + | Node::Arm(..) + | Node::Local(..) + | Node::Visibility(..) + | Node::Crate(..) + | Node::Ty(..) + | Node::TraitRef(..) + | Node::Infer(..) => None, } } From 08ceac8ee3d740c48e6bb250de0798fcbe0824f4 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 21 Aug 2021 12:29:11 -0700 Subject: [PATCH 06/32] Add cross-crate tuple field count error test --- ...clarations-for-tuple-field-count-errors.rs | 20 + .../ui/pattern/pat-tuple-field-count-cross.rs | 57 ++ .../pat-tuple-field-count-cross.stderr | 536 ++++++++++++++++++ 3 files changed, 613 insertions(+) create mode 100644 src/test/ui/pattern/auxiliary/declarations-for-tuple-field-count-errors.rs create mode 100644 src/test/ui/pattern/pat-tuple-field-count-cross.rs create mode 100644 src/test/ui/pattern/pat-tuple-field-count-cross.stderr diff --git a/src/test/ui/pattern/auxiliary/declarations-for-tuple-field-count-errors.rs b/src/test/ui/pattern/auxiliary/declarations-for-tuple-field-count-errors.rs new file mode 100644 index 0000000000000..f7373c453966c --- /dev/null +++ b/src/test/ui/pattern/auxiliary/declarations-for-tuple-field-count-errors.rs @@ -0,0 +1,20 @@ +pub struct Z0; +pub struct Z1(); + +pub struct S(pub u8, pub u8, pub u8); +pub struct M( + pub u8, + pub u8, + pub u8, +); + +pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + +pub enum E2 { + S(u8, u8, u8), + M( + u8, + u8, + u8, + ), +} diff --git a/src/test/ui/pattern/pat-tuple-field-count-cross.rs b/src/test/ui/pattern/pat-tuple-field-count-cross.rs new file mode 100644 index 0000000000000..b63da4e154f73 --- /dev/null +++ b/src/test/ui/pattern/pat-tuple-field-count-cross.rs @@ -0,0 +1,57 @@ +// aux-build:declarations-for-tuple-field-count-errors.rs + +extern crate declarations_for_tuple_field_count_errors; + +use declarations_for_tuple_field_count_errors::*; + +fn main() { + match Z0 { + Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0` + Z0(x) => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0` + } + match Z1() { + Z1 => {} //~ ERROR match bindings cannot shadow tuple structs + Z1(x) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 0 fields + } + + match S(1, 2, 3) { + S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple struct has 3 fields + S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields + S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 3 fields + S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields + } + match M(1, 2, 3) { + M() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple struct has 3 fields + M(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields + M(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 3 fields + M(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields + } + + match E1::Z0 { + E1::Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0` + E1::Z0(x) => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0` + } + match E1::Z1() { + E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1` + E1::Z1(x) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 0 fields + } + match E1::S(1, 2, 3) { + E1::S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields + E1::S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields + E1::S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields + E1::S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields + } + + match E2::S(1, 2, 3) { + E2::S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields + E2::S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields + E2::S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields + E2::S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields + } + match E2::M(1, 2, 3) { + E2::M() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields + E2::M(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields + E2::M(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields + E2::M(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields + } +} diff --git a/src/test/ui/pattern/pat-tuple-field-count-cross.stderr b/src/test/ui/pattern/pat-tuple-field-count-cross.stderr new file mode 100644 index 0000000000000..570bf0cbc0810 --- /dev/null +++ b/src/test/ui/pattern/pat-tuple-field-count-cross.stderr @@ -0,0 +1,536 @@ +error[E0530]: match bindings cannot shadow tuple structs + --> $DIR/pat-tuple-field-count-cross.rs:13:9 + | +LL | use declarations_for_tuple_field_count_errors::*; + | -------------------------------------------- the tuple struct `Z1` is imported here +... +LL | Z1 => {} + | ^^ cannot be named the same as a tuple struct + +error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` + --> $DIR/pat-tuple-field-count-cross.rs:9:9 + | +LL | Z0() => {} + | ^^^^ + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:1:1 + | +LL | pub struct Z0; + | -------------- `Z0` defined here +LL | pub struct Z1(); + | ---------------- similarly named tuple struct `Z1` defined here + | +help: use this syntax instead + | +LL | Z0 => {} + | ~~ +help: a tuple struct with a similar name exists + | +LL | Z1() => {} + | ~~ + +error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` + --> $DIR/pat-tuple-field-count-cross.rs:10:9 + | +LL | Z0(x) => {} + | ^^^^^ + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:1:1 + | +LL | pub struct Z0; + | -------------- `Z0` defined here +LL | pub struct Z1(); + | ---------------- similarly named tuple struct `Z1` defined here + | +help: use this syntax instead + | +LL | Z0 => {} + | ~~ +help: a tuple struct with a similar name exists + | +LL | Z1(x) => {} + | ~~ + +error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` + --> $DIR/pat-tuple-field-count-cross.rs:31:9 + | +LL | E1::Z0() => {} + | ^^^^^^^^ + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:15 + | +LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + | -- ---- similarly named tuple variant `Z1` defined here + | | + | `E1::Z0` defined here + | +help: use this syntax instead + | +LL | E1::Z0 => {} + | ~~~~~~ +help: a tuple variant with a similar name exists + | +LL | E1::Z1() => {} + | ~~ + +error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` + --> $DIR/pat-tuple-field-count-cross.rs:32:9 + | +LL | E1::Z0(x) => {} + | ^^^^^^^^^ + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:15 + | +LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + | -- ---- similarly named tuple variant `Z1` defined here + | | + | `E1::Z0` defined here + | +help: use this syntax instead + | +LL | E1::Z0 => {} + | ~~~~~~ +help: a tuple variant with a similar name exists + | +LL | E1::Z1(x) => {} + | ~~ + +error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1` + --> $DIR/pat-tuple-field-count-cross.rs:35:9 + | +LL | E1::Z1 => {} + | ^^^^^^ + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19 + | +LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + | -- ---- `E1::Z1` defined here + | | + | similarly named unit variant `Z0` defined here + | +help: use the tuple variant pattern syntax instead + | +LL | E1::Z1(/* fields */) => {} + | ~~~~~~~~~~~~~~~~~~~~ +help: a unit variant with a similar name exists + | +LL | E1::Z0 => {} + | ~~ + +error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields + --> $DIR/pat-tuple-field-count-cross.rs:14:12 + | +LL | Z1(x) => {} + | -- ^ expected 0 fields, found 1 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:2:1 + | +LL | pub struct Z1(); + | ---------------- tuple struct has 0 fields + +error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:18:10 + | +LL | S() => {} + | -^^ expected 3 fields, found 0 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14 + | +LL | pub struct S(pub u8, pub u8, pub u8); + | ------ ------ ------ tuple struct has 3 fields + | +help: use `_` to explicitly ignore each field + | +LL | S(_, _, _) => {} + | +++++++ +help: use `..` to ignore all fields + | +LL | S(..) => {} + | ++ + +error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:19:11 + | +LL | S(1) => {} + | - ^ expected 3 fields, found 1 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14 + | +LL | pub struct S(pub u8, pub u8, pub u8); + | ------ ------ ------ tuple struct has 3 fields + | +help: use `_` to explicitly ignore each field + | +LL | S(1, _, _) => {} + | ++++++ +help: use `..` to ignore the rest of the fields + | +LL | S(1, ..) => {} + | ++++ + +error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:20:11 + | +LL | S(xyz, abc) => {} + | - ^^^ ^^^ expected 3 fields, found 2 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14 + | +LL | pub struct S(pub u8, pub u8, pub u8); + | ------ ------ ------ tuple struct has 3 fields + | +help: use `_` to explicitly ignore each field + | +LL | S(xyz, abc, _) => {} + | +++ + +error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:21:11 + | +LL | S(1, 2, 3, 4) => {} + | - ^ ^ ^ ^ expected 3 fields, found 4 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14 + | +LL | pub struct S(pub u8, pub u8, pub u8); + | ------ ------ ------ tuple struct has 3 fields + +error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:24:10 + | +LL | M() => {} + | -^^ expected 3 fields, found 0 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1 + | +LL | / pub struct M( +LL | | pub u8, + | | ------ +LL | | pub u8, + | | ------ +LL | | pub u8, + | | ------ tuple struct has 3 fields +LL | | ); + | |__- tuple struct defined here + | +help: use `_` to explicitly ignore each field + | +LL | M(_, _, _) => {} + | +++++++ +help: use `..` to ignore all fields + | +LL | M(..) => {} + | ++ + +error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:25:11 + | +LL | M(1) => {} + | - ^ expected 3 fields, found 1 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1 + | +LL | / pub struct M( +LL | | pub u8, + | | ------ +LL | | pub u8, + | | ------ +LL | | pub u8, + | | ------ tuple struct has 3 fields +LL | | ); + | |__- tuple struct defined here + | +help: use `_` to explicitly ignore each field + | +LL | M(1, _, _) => {} + | ++++++ +help: use `..` to ignore the rest of the fields + | +LL | M(1, ..) => {} + | ++++ + +error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:26:11 + | +LL | M(xyz, abc) => {} + | - ^^^ ^^^ expected 3 fields, found 2 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1 + | +LL | / pub struct M( +LL | | pub u8, + | | ------ +LL | | pub u8, + | | ------ +LL | | pub u8, + | | ------ tuple struct has 3 fields +LL | | ); + | |__- tuple struct defined here + | +help: use `_` to explicitly ignore each field + | +LL | M(xyz, abc, _) => {} + | +++ + +error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:27:11 + | +LL | M(1, 2, 3, 4) => {} + | - ^ ^ ^ ^ expected 3 fields, found 4 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1 + | +LL | / pub struct M( +LL | | pub u8, + | | ------ +LL | | pub u8, + | | ------ +LL | | pub u8, + | | ------ tuple struct has 3 fields +LL | | ); + | |__- tuple struct defined here + +error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields + --> $DIR/pat-tuple-field-count-cross.rs:36:16 + | +LL | E1::Z1(x) => {} + | ------ ^ expected 0 fields, found 1 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19 + | +LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + | ---- tuple variant has 0 fields + +error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:39:14 + | +LL | E1::S() => {} + | -----^^ expected 3 fields, found 0 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27 + | +LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + | -- -- -- tuple variant has 3 fields + | +help: use `_` to explicitly ignore each field + | +LL | E1::S(_, _, _) => {} + | +++++++ +help: use `..` to ignore all fields + | +LL | E1::S(..) => {} + | ++ + +error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:40:15 + | +LL | E1::S(1) => {} + | ----- ^ expected 3 fields, found 1 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27 + | +LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + | -- -- -- tuple variant has 3 fields + | +help: use `_` to explicitly ignore each field + | +LL | E1::S(1, _, _) => {} + | ++++++ +help: use `..` to ignore the rest of the fields + | +LL | E1::S(1, ..) => {} + | ++++ + +error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:41:15 + | +LL | E1::S(xyz, abc) => {} + | ----- ^^^ ^^^ expected 3 fields, found 2 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27 + | +LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + | -- -- -- tuple variant has 3 fields + | +help: use `_` to explicitly ignore each field + | +LL | E1::S(xyz, abc, _) => {} + | +++ + +error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:42:15 + | +LL | E1::S(1, 2, 3, 4) => {} + | ----- ^ ^ ^ ^ expected 3 fields, found 4 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27 + | +LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + | -- -- -- tuple variant has 3 fields + +error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:46:14 + | +LL | E2::S() => {} + | -----^^ expected 3 fields, found 0 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7 + | +LL | S(u8, u8, u8), + | -- -- -- tuple variant has 3 fields + | +help: use `_` to explicitly ignore each field + | +LL | E2::S(_, _, _) => {} + | +++++++ +help: use `..` to ignore all fields + | +LL | E2::S(..) => {} + | ++ + +error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:47:15 + | +LL | E2::S(1) => {} + | ----- ^ expected 3 fields, found 1 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7 + | +LL | S(u8, u8, u8), + | -- -- -- tuple variant has 3 fields + | +help: use `_` to explicitly ignore each field + | +LL | E2::S(1, _, _) => {} + | ++++++ +help: use `..` to ignore the rest of the fields + | +LL | E2::S(1, ..) => {} + | ++++ + +error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:48:15 + | +LL | E2::S(xyz, abc) => {} + | ----- ^^^ ^^^ expected 3 fields, found 2 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7 + | +LL | S(u8, u8, u8), + | -- -- -- tuple variant has 3 fields + | +help: use `_` to explicitly ignore each field + | +LL | E2::S(xyz, abc, _) => {} + | +++ + +error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:49:15 + | +LL | E2::S(1, 2, 3, 4) => {} + | ----- ^ ^ ^ ^ expected 3 fields, found 4 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7 + | +LL | S(u8, u8, u8), + | -- -- -- tuple variant has 3 fields + +error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:52:14 + | +LL | E2::M() => {} + | -----^^ expected 3 fields, found 0 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5 + | +LL | / M( +LL | | u8, + | | -- +LL | | u8, + | | -- +LL | | u8, + | | -- tuple variant has 3 fields +LL | | ), + | |_____- tuple variant defined here + | +help: use `_` to explicitly ignore each field + | +LL | E2::M(_, _, _) => {} + | +++++++ +help: use `..` to ignore all fields + | +LL | E2::M(..) => {} + | ++ + +error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:53:15 + | +LL | E2::M(1) => {} + | ----- ^ expected 3 fields, found 1 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5 + | +LL | / M( +LL | | u8, + | | -- +LL | | u8, + | | -- +LL | | u8, + | | -- tuple variant has 3 fields +LL | | ), + | |_____- tuple variant defined here + | +help: use `_` to explicitly ignore each field + | +LL | E2::M(1, _, _) => {} + | ++++++ +help: use `..` to ignore the rest of the fields + | +LL | E2::M(1, ..) => {} + | ++++ + +error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:54:15 + | +LL | E2::M(xyz, abc) => {} + | ----- ^^^ ^^^ expected 3 fields, found 2 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5 + | +LL | / M( +LL | | u8, + | | -- +LL | | u8, + | | -- +LL | | u8, + | | -- tuple variant has 3 fields +LL | | ), + | |_____- tuple variant defined here + | +help: use `_` to explicitly ignore each field + | +LL | E2::M(xyz, abc, _) => {} + | +++ + +error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has 3 fields + --> $DIR/pat-tuple-field-count-cross.rs:55:15 + | +LL | E2::M(1, 2, 3, 4) => {} + | ----- ^ ^ ^ ^ expected 3 fields, found 4 + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5 + | +LL | / M( +LL | | u8, + | | -- +LL | | u8, + | | -- +LL | | u8, + | | -- tuple variant has 3 fields +LL | | ), + | |_____- tuple variant defined here + +error: aborting due to 28 previous errors + +Some errors have detailed explanations: E0023, E0530, E0532. +For more information about an error, try `rustc --explain E0023`. From 19f45101e72ed6880b0fd1ebee73d74ea782c8c4 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 21 Aug 2021 18:41:34 -0700 Subject: [PATCH 07/32] Bless tests --- .../ui/pattern/pat-tuple-overfield.stderr | 34 +++++++++---------- ...priority-higher-than-other-inherent.stderr | 6 ++++ .../ui/typeck/struct-enum-wrong-args.stderr | 30 ++++++++++++++++ 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr index 1df9c1c11b8a5..646ac4e661897 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.stderr +++ b/src/test/ui/pattern/pat-tuple-overfield.stderr @@ -1,5 +1,5 @@ error[E0530]: match bindings cannot shadow tuple structs - --> $DIR/pat-tuple-overfield.rs:43:9 + --> $DIR/pat-tuple-overfield.rs:41:9 | LL | struct Z1(); | ------------ the tuple struct `Z1` is defined here @@ -8,7 +8,7 @@ LL | Z1 => {} | ^^ cannot be named the same as a tuple struct error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` - --> $DIR/pat-tuple-overfield.rs:38:9 + --> $DIR/pat-tuple-overfield.rs:36:9 | LL | struct Z0; | ---------- `Z0` defined here @@ -28,7 +28,7 @@ LL | Z1() => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` - --> $DIR/pat-tuple-overfield.rs:39:9 + --> $DIR/pat-tuple-overfield.rs:37:9 | LL | struct Z0; | ---------- `Z0` defined here @@ -48,7 +48,7 @@ LL | Z1(_) => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` - --> $DIR/pat-tuple-overfield.rs:40:9 + --> $DIR/pat-tuple-overfield.rs:38:9 | LL | struct Z0; | ---------- `Z0` defined here @@ -68,7 +68,7 @@ LL | Z1(_, _) => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` - --> $DIR/pat-tuple-overfield.rs:50:9 + --> $DIR/pat-tuple-overfield.rs:48:9 | LL | Z0, | -- `E1::Z0` defined here @@ -88,7 +88,7 @@ LL | E1::Z1() => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` - --> $DIR/pat-tuple-overfield.rs:51:9 + --> $DIR/pat-tuple-overfield.rs:49:9 | LL | Z0, | -- `E1::Z0` defined here @@ -108,7 +108,7 @@ LL | E1::Z1(_) => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` - --> $DIR/pat-tuple-overfield.rs:52:9 + --> $DIR/pat-tuple-overfield.rs:50:9 | LL | Z0, | -- `E1::Z0` defined here @@ -128,7 +128,7 @@ LL | E1::Z1(_, _) => {} | ~~ error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1` - --> $DIR/pat-tuple-overfield.rs:55:9 + --> $DIR/pat-tuple-overfield.rs:53:9 | LL | Z0, | -- similarly named unit variant `Z0` defined here @@ -148,7 +148,7 @@ LL | E1::Z0 => {} | ~~ error[E0308]: mismatched types - --> $DIR/pat-tuple-overfield.rs:21:9 + --> $DIR/pat-tuple-overfield.rs:19:9 | LL | match (1, 2, 3) { | --------- this expression has type `({integer}, {integer}, {integer})` @@ -159,7 +159,7 @@ LL | (1, 2, 3, 4) => {} found tuple `(_, _, _, _)` error[E0308]: mismatched types - --> $DIR/pat-tuple-overfield.rs:22:9 + --> $DIR/pat-tuple-overfield.rs:20:9 | LL | match (1, 2, 3) { | --------- this expression has type `({integer}, {integer}, {integer})` @@ -171,7 +171,7 @@ LL | (1, 2, .., 3, 4) => {} found tuple `(_, _, _, _)` error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-overfield.rs:26:11 + --> $DIR/pat-tuple-overfield.rs:24:11 | LL | struct S(u8, u8, u8); | -- -- -- tuple struct has 3 fields @@ -180,7 +180,7 @@ LL | S(1, 2, 3, 4) => {} | - ^ ^ ^ ^ expected 3 fields, found 4 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-overfield.rs:28:11 + --> $DIR/pat-tuple-overfield.rs:26:11 | LL | struct S(u8, u8, u8); | -- -- -- tuple struct has 3 fields @@ -189,7 +189,7 @@ LL | S(1, 2, .., 3, 4) => {} | - ^ ^ ^ ^ expected 3 fields, found 4 error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields - --> $DIR/pat-tuple-overfield.rs:33:11 + --> $DIR/pat-tuple-overfield.rs:31:11 | LL | struct M( | - tuple struct defined here @@ -208,7 +208,7 @@ LL | M(1, 2, 3, 4, 5, 6) => {} | - ^ ^ ^ ^ ^ ^ expected 5 fields, found 6 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields - --> $DIR/pat-tuple-overfield.rs:45:12 + --> $DIR/pat-tuple-overfield.rs:43:12 | LL | struct Z1(); | --- tuple struct has 0 fields @@ -217,7 +217,7 @@ LL | Z1(_) => {} | -- ^ expected 0 fields, found 1 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 0 fields - --> $DIR/pat-tuple-overfield.rs:46:12 + --> $DIR/pat-tuple-overfield.rs:44:12 | LL | struct Z1(); | --- tuple struct has 0 fields @@ -226,7 +226,7 @@ LL | Z1(_, _) => {} | -- ^ ^ expected 0 fields, found 2 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields - --> $DIR/pat-tuple-overfield.rs:57:16 + --> $DIR/pat-tuple-overfield.rs:55:16 | LL | Z1(), | -- tuple variant has 0 fields @@ -235,7 +235,7 @@ LL | E1::Z1(_) => {} | ------ ^ expected 0 fields, found 1 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 0 fields - --> $DIR/pat-tuple-overfield.rs:58:16 + --> $DIR/pat-tuple-overfield.rs:56:16 | LL | Z1(), | -- tuple variant has 0 fields diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr index 1d520613a288f..37543c137f66f 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr @@ -5,6 +5,12 @@ LL | ::V(); | ^^^^^^-- supplied 0 arguments | | | expected 1 argument + | +note: tuple variant defined here + --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:5:5 + | +LL | V(u8) + | ^ error[E0308]: mismatched types --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17 diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr index d77ef73028b0c..6e99feed33f9c 100644 --- a/src/test/ui/typeck/struct-enum-wrong-args.stderr +++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr @@ -29,6 +29,12 @@ LL | let _ = Wrapper(); | ^^^^^^^-- supplied 0 arguments | | | expected 1 argument + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:2:8 + | +LL | struct Wrapper(i32); + | ^^^^^^^ error[E0061]: this struct takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:10:13 @@ -37,6 +43,12 @@ LL | let _ = Wrapper(5, 2); | ^^^^^^^ - - supplied 2 arguments | | | expected 1 argument + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:2:8 + | +LL | struct Wrapper(i32); + | ^^^^^^^ error[E0061]: this struct takes 2 arguments but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:11:13 @@ -45,6 +57,12 @@ LL | let _ = DoubleWrapper(); | ^^^^^^^^^^^^^-- supplied 0 arguments | | | expected 2 arguments + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:3:8 + | +LL | struct DoubleWrapper(i32, i32); + | ^^^^^^^^^^^^^ error[E0061]: this struct takes 2 arguments but 1 argument was supplied --> $DIR/struct-enum-wrong-args.rs:12:13 @@ -53,6 +71,12 @@ LL | let _ = DoubleWrapper(5); | ^^^^^^^^^^^^^ - supplied 1 argument | | | expected 2 arguments + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:3:8 + | +LL | struct DoubleWrapper(i32, i32); + | ^^^^^^^^^^^^^ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:13:13 @@ -61,6 +85,12 @@ LL | let _ = DoubleWrapper(5, 2, 7); | ^^^^^^^^^^^^^ - - - supplied 3 arguments | | | expected 2 arguments + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:3:8 + | +LL | struct DoubleWrapper(i32, i32); + | ^^^^^^^^^^^^^ error: aborting due to 8 previous errors From f28793dd13e8a8132d559629728e6ca9514dbe36 Mon Sep 17 00:00:00 2001 From: linux1 Date: Fri, 6 Aug 2021 17:53:29 -0400 Subject: [PATCH 08/32] Feat: added inline asm support for s390x --- compiler/rustc_codegen_llvm/src/asm.rs | 6 + compiler/rustc_target/src/asm/mod.rs | 25 ++++ compiler/rustc_target/src/asm/s390x.rs | 156 +++++++++++++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 compiler/rustc_target/src/asm/s390x.rs diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 4387f5301a58d..938f036da0e4a 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -314,6 +314,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {} InlineAsmArch::Hexagon => {} InlineAsmArch::Mips | InlineAsmArch::Mips64 => {} + InlineAsmArch::s390 => {} InlineAsmArch::SpirV => {} InlineAsmArch::Wasm32 => {} InlineAsmArch::Bpf => {} @@ -633,6 +634,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>) InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", + InlineAsmRegClass::s390x(s390xInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::s390x(s390xInlineAsmRegClass::freg) => "f", InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } @@ -711,6 +714,7 @@ fn modifier_to_llvm( } InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None, InlineAsmRegClass::Bpf(_) => None, + InlineAsmRegClass::s390x(_) => None, InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } @@ -769,6 +773,8 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(), InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(), InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(), + InlineAsmRegClass::s390x(s390xInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::s390x(s390xInlineAsmRegClass::freg) => cx.type_f64(), InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 9ebf8235e2098..3ce5a8195d601 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -154,6 +154,7 @@ mod mips; mod nvptx; mod powerpc; mod riscv; +mod s390x; mod spirv; mod wasm; mod x86; @@ -166,6 +167,7 @@ pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass}; pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass}; pub use powerpc::{PowerPCInlineAsmReg, PowerPCInlineAsmRegClass}; pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass}; +pub use s390x::{s390xInlineAsmReg, s390xInlineAsmRegClass}; pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass}; pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass}; pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass}; @@ -184,6 +186,7 @@ pub enum InlineAsmArch { Mips64, PowerPC, PowerPC64, + s390x, SpirV, Wasm32, Bpf, @@ -206,6 +209,7 @@ impl FromStr for InlineAsmArch { "hexagon" => Ok(Self::Hexagon), "mips" => Ok(Self::Mips), "mips64" => Ok(Self::Mips64), + "s390x" => Ok(Self::s390x), "spirv" => Ok(Self::SpirV), "wasm32" => Ok(Self::Wasm32), "bpf" => Ok(Self::Bpf), @@ -235,6 +239,7 @@ pub enum InlineAsmReg { PowerPC(PowerPCInlineAsmReg), Hexagon(HexagonInlineAsmReg), Mips(MipsInlineAsmReg), + s390x(InlineAsmReg), SpirV(SpirVInlineAsmReg), Wasm(WasmInlineAsmReg), Bpf(BpfInlineAsmReg), @@ -252,6 +257,7 @@ impl InlineAsmReg { Self::PowerPC(r) => r.name(), Self::Hexagon(r) => r.name(), Self::Mips(r) => r.name(), + Self::s390x(r) => r.name(), Self::Bpf(r) => r.name(), Self::Err => "", } @@ -266,6 +272,7 @@ impl InlineAsmReg { Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()), Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()), Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()), + Self::s390x(r) => InlineAsmRegClass::s390x(r.reg_class()), Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()), Self::Err => InlineAsmRegClass::Err, } @@ -305,6 +312,9 @@ impl InlineAsmReg { InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, &name)?) } + InlineAsmArch::s390x => { + Self::s390x(s390xInlineAsmReg::parse(arch, has_feature, target, &name)?) + } InlineAsmArch::SpirV => { Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?) } @@ -333,6 +343,7 @@ impl InlineAsmReg { Self::PowerPC(r) => r.emit(out, arch, modifier), Self::Hexagon(r) => r.emit(out, arch, modifier), Self::Mips(r) => r.emit(out, arch, modifier), + Self::s390x(r) => r.emit(out, arch, modifier), Self::Bpf(r) => r.emit(out, arch, modifier), Self::Err => unreachable!("Use of InlineAsmReg::Err"), } @@ -347,6 +358,7 @@ impl InlineAsmReg { Self::PowerPC(_) => cb(self), Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))), Self::Mips(_) => cb(self), + Self::s390x(_) => cb(self), Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))), Self::Err => unreachable!("Use of InlineAsmReg::Err"), } @@ -374,6 +386,7 @@ pub enum InlineAsmRegClass { PowerPC(PowerPCInlineAsmRegClass), Hexagon(HexagonInlineAsmRegClass), Mips(MipsInlineAsmRegClass), + s390x(s390xInlineAsmRegClass), SpirV(SpirVInlineAsmRegClass), Wasm(WasmInlineAsmRegClass), Bpf(BpfInlineAsmRegClass), @@ -392,6 +405,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.name(), Self::Hexagon(r) => r.name(), Self::Mips(r) => r.name(), + Self::s390x(r) => r.name(), Self::SpirV(r) => r.name(), Self::Wasm(r) => r.name(), Self::Bpf(r) => r.name(), @@ -412,6 +426,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC), Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon), Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips), + Self::s390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::s390x), Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV), Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm), Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf), @@ -439,6 +454,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.suggest_modifier(arch, ty), Self::Hexagon(r) => r.suggest_modifier(arch, ty), Self::Mips(r) => r.suggest_modifier(arch, ty), + Self::s390x(r) => r.suggest_modifier(arch, ty), Self::SpirV(r) => r.suggest_modifier(arch, ty), Self::Wasm(r) => r.suggest_modifier(arch, ty), Self::Bpf(r) => r.suggest_modifier(arch, ty), @@ -462,6 +478,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.default_modifier(arch), Self::Hexagon(r) => r.default_modifier(arch), Self::Mips(r) => r.default_modifier(arch), + Self::s390x(r) => r.default_modifier(arch), Self::SpirV(r) => r.default_modifier(arch), Self::Wasm(r) => r.default_modifier(arch), Self::Bpf(r) => r.default_modifier(arch), @@ -484,6 +501,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.supported_types(arch), Self::Hexagon(r) => r.supported_types(arch), Self::Mips(r) => r.supported_types(arch), + Self::s390x(r) => r.supported_types(arch), Self::SpirV(r) => r.supported_types(arch), Self::Wasm(r) => r.supported_types(arch), Self::Bpf(r) => r.supported_types(arch), @@ -509,6 +527,7 @@ impl InlineAsmRegClass { InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?) } + InlineAsmArch::s390x => Self::s390x(s390xInlineAsmRegClass::parse(arch, name)?), InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?), InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?), InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(arch, name)?), @@ -527,6 +546,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.valid_modifiers(arch), Self::Hexagon(r) => r.valid_modifiers(arch), Self::Mips(r) => r.valid_modifiers(arch), + Self::s390x(r) => r.valid_modifiers(arch), Self::SpirV(r) => r.valid_modifiers(arch), Self::Wasm(r) => r.valid_modifiers(arch), Self::Bpf(r) => r.valid_modifiers(arch), @@ -695,6 +715,11 @@ pub fn allocatable_registers( mips::fill_reg_map(arch, has_feature, target, &mut map); map } + InlineAsmArch::s390x => { + let mut map = s390x::regclass_map(); + s390x::fill_reg_map(arch, has_feature, target, &mut map); + map + } InlineAsmArch::SpirV => { let mut map = spirv::regclass_map(); spirv::fill_reg_map(arch, has_feature, target, &mut map); diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs new file mode 100644 index 0000000000000..ad07e20de8a02 --- /dev/null +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -0,0 +1,156 @@ +use super::{InlineAsmArch, InlineAsmType}; +use rustc_macros::HashStable_Generic; +use std::fmt; + +def_reg_class! { + s390x s390xInlineAsmRegClass { + reg, + freg, + } +} + +impl s390xInlineAsmRegClass { + pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] { + &[] + } + + pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option { + None + } + + pub fn suggest_modifier( + self, + _arch: InlineAsmArch, + _ty: InlineAsmType, + ) -> Option<(char, &'static str)> { + None + } + + pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> { + None + } + + pub fn supported_types( + self, + arch: InlineAsmArch, + ) -> &'static [(InlineAsmType, Option<&'static str>)] { + match (self, arch) { + (Self::reg, _) => types! { _: I8, I16, I32; }, + (Self::freg, _) => types! { _: F32, F64; }, + } + } +} + +def_regs! { + s390x s390xInlineAsmReg s390xInlineAsmRegClass { + r0: req = ["r0"], + r1: reg = ["r1"], + r2: reg = ["r2"], + r3: reg = ["r3"], + r4: reg = ["r4"], + r5: reg = ["r5"], + r6: reg = ["r6"], + r7: reg = ["r7"], + r8: reg = ["r8"], + r9: reg = ["r9"], + r10: reg = ["r10"], + r11: reg = ["r11"], + r12: reg = ["r12"], + r14: reg = ["r14"], + f0: freg = ["f0"], + f1: freg = ["f1"], + f2: freg = ["f2"], + f3: freg = ["f3"], + f4: freg = ["f4"], + f5: freg = ["f5"], + f6: freg = ["f6"], + f7: freg = ["f7"], + f8: freg = ["f8"], + f9: freg = ["f9"], + f10: freg = ["f10"], + f11: freg = ["f11"], + f12: freg = ["f12"], + f13: freg = ["f13"], + f14: freg = ["f14"], + f15: freg = ["f15"], + #error = ["r13"] => + "The base pointer cannot be used as an operand for inline asm", + #error = ["r15"] => + "The stack pointer cannot be used as an operand for inline asm", + #error = ["a0"] => + "This pointer is reserved on s390x and cannot be used as an operand for inline asm", + #error = ["a1"] => + "This pointer is reserved on z/Arch and cannot be used as an operand for inline asm", + #error = ["c0"] => + "c0 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c1"] => + "c1 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c2"] => + "c2 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c3"] => + "c3 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c4"] => + "c4 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c5"] => + "c5 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c6"] => + "c6 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c7"] => + "c7 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c8"] => + "c8 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c9"] => + "c9 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c10"] => + "c10 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c11"] => + "c11 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c12"] => + "c12 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c13"] => + "c13 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c14"] => + "c14 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["c15"] => + "c15 is reserved by the kernel and cannot be used as an operand for inline asm", + #error = ["a2"] => + "a2 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a3"] => + "a3 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a4"] => + "a4 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a5"] => + "a5 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a6"] => + "a6 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a7"] => + "a7 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a8"] => + "a8 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a9"] => + "a9 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a10"] => + "a10 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a11"] => + "a11 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a12"] => + "a12 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a13"] => + "a13 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a14"] => + "a14 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = ["a15"] => + "a15 is not supported by LLVM and cannot be used as an operand for inline asm", + } +} + +impl s390xInlineAsmReg { + pub fn emit( + self, + out: &mut dyn fmt::Write, + _arch: InlineAsmArch, + _modifier: Option, + ) -> fmt::Result { + out.write_str(self.name()) + } +} From 5f5afba5fbb869db26c4f9e88c29bad94007dfd1 Mon Sep 17 00:00:00 2001 From: linux1 Date: Wed, 18 Aug 2021 11:25:50 -0400 Subject: [PATCH 09/32] Feat: added s390x reg-definitions, constraint codes, and tests --- compiler/rustc_codegen_llvm/src/asm.rs | 12 ++-- compiler/rustc_target/src/asm/mod.rs | 42 ++++++------- compiler/rustc_target/src/asm/s390x.rs | 10 +-- src/test/assembly/asm/s390x-types.rs | 86 ++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 32 deletions(-) create mode 100644 src/test/assembly/asm/s390x-types.rs diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 938f036da0e4a..1689fdd4f2e81 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -314,7 +314,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {} InlineAsmArch::Hexagon => {} InlineAsmArch::Mips | InlineAsmArch::Mips64 => {} - InlineAsmArch::s390 => {} + InlineAsmArch::S390x => {} InlineAsmArch::SpirV => {} InlineAsmArch::Wasm32 => {} InlineAsmArch::Bpf => {} @@ -634,8 +634,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>) InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", - InlineAsmRegClass::s390x(s390xInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::s390x(s390xInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } @@ -714,7 +714,7 @@ fn modifier_to_llvm( } InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None, InlineAsmRegClass::Bpf(_) => None, - InlineAsmRegClass::s390x(_) => None, + InlineAsmRegClass::S390x(_) => None, InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } @@ -773,8 +773,8 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(), InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(), InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(), - InlineAsmRegClass::s390x(s390xInlineAsmRegClass::reg) => cx.type_i32(), - InlineAsmRegClass::s390x(s390xInlineAsmRegClass::freg) => cx.type_f64(), + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 3ce5a8195d601..015faa14e28af 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -167,7 +167,7 @@ pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass}; pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass}; pub use powerpc::{PowerPCInlineAsmReg, PowerPCInlineAsmRegClass}; pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass}; -pub use s390x::{s390xInlineAsmReg, s390xInlineAsmRegClass}; +pub use s390x::{S390xInlineAsmReg, S390xInlineAsmRegClass}; pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass}; pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass}; pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass}; @@ -186,7 +186,7 @@ pub enum InlineAsmArch { Mips64, PowerPC, PowerPC64, - s390x, + S390x, SpirV, Wasm32, Bpf, @@ -209,7 +209,7 @@ impl FromStr for InlineAsmArch { "hexagon" => Ok(Self::Hexagon), "mips" => Ok(Self::Mips), "mips64" => Ok(Self::Mips64), - "s390x" => Ok(Self::s390x), + "s390x" => Ok(Self::S390x), "spirv" => Ok(Self::SpirV), "wasm32" => Ok(Self::Wasm32), "bpf" => Ok(Self::Bpf), @@ -239,7 +239,7 @@ pub enum InlineAsmReg { PowerPC(PowerPCInlineAsmReg), Hexagon(HexagonInlineAsmReg), Mips(MipsInlineAsmReg), - s390x(InlineAsmReg), + S390x(S390xInlineAsmReg), SpirV(SpirVInlineAsmReg), Wasm(WasmInlineAsmReg), Bpf(BpfInlineAsmReg), @@ -257,7 +257,7 @@ impl InlineAsmReg { Self::PowerPC(r) => r.name(), Self::Hexagon(r) => r.name(), Self::Mips(r) => r.name(), - Self::s390x(r) => r.name(), + Self::S390x(r) => r.name(), Self::Bpf(r) => r.name(), Self::Err => "", } @@ -272,7 +272,7 @@ impl InlineAsmReg { Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()), Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()), Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()), - Self::s390x(r) => InlineAsmRegClass::s390x(r.reg_class()), + Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()), Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()), Self::Err => InlineAsmRegClass::Err, } @@ -312,8 +312,8 @@ impl InlineAsmReg { InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, &name)?) } - InlineAsmArch::s390x => { - Self::s390x(s390xInlineAsmReg::parse(arch, has_feature, target, &name)?) + InlineAsmArch::S390x => { + Self::S390x(S390xInlineAsmReg::parse(arch, has_feature, target, &name)?) } InlineAsmArch::SpirV => { Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?) @@ -343,7 +343,7 @@ impl InlineAsmReg { Self::PowerPC(r) => r.emit(out, arch, modifier), Self::Hexagon(r) => r.emit(out, arch, modifier), Self::Mips(r) => r.emit(out, arch, modifier), - Self::s390x(r) => r.emit(out, arch, modifier), + Self::S390x(r) => r.emit(out, arch, modifier), Self::Bpf(r) => r.emit(out, arch, modifier), Self::Err => unreachable!("Use of InlineAsmReg::Err"), } @@ -358,7 +358,7 @@ impl InlineAsmReg { Self::PowerPC(_) => cb(self), Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))), Self::Mips(_) => cb(self), - Self::s390x(_) => cb(self), + Self::S390x(_) => cb(self), Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))), Self::Err => unreachable!("Use of InlineAsmReg::Err"), } @@ -386,7 +386,7 @@ pub enum InlineAsmRegClass { PowerPC(PowerPCInlineAsmRegClass), Hexagon(HexagonInlineAsmRegClass), Mips(MipsInlineAsmRegClass), - s390x(s390xInlineAsmRegClass), + S390x(S390xInlineAsmRegClass), SpirV(SpirVInlineAsmRegClass), Wasm(WasmInlineAsmRegClass), Bpf(BpfInlineAsmRegClass), @@ -405,7 +405,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.name(), Self::Hexagon(r) => r.name(), Self::Mips(r) => r.name(), - Self::s390x(r) => r.name(), + Self::S390x(r) => r.name(), Self::SpirV(r) => r.name(), Self::Wasm(r) => r.name(), Self::Bpf(r) => r.name(), @@ -426,7 +426,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC), Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon), Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips), - Self::s390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::s390x), + Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x), Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV), Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm), Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf), @@ -454,7 +454,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.suggest_modifier(arch, ty), Self::Hexagon(r) => r.suggest_modifier(arch, ty), Self::Mips(r) => r.suggest_modifier(arch, ty), - Self::s390x(r) => r.suggest_modifier(arch, ty), + Self::S390x(r) => r.suggest_modifier(arch, ty), Self::SpirV(r) => r.suggest_modifier(arch, ty), Self::Wasm(r) => r.suggest_modifier(arch, ty), Self::Bpf(r) => r.suggest_modifier(arch, ty), @@ -478,7 +478,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.default_modifier(arch), Self::Hexagon(r) => r.default_modifier(arch), Self::Mips(r) => r.default_modifier(arch), - Self::s390x(r) => r.default_modifier(arch), + Self::S390x(r) => r.default_modifier(arch), Self::SpirV(r) => r.default_modifier(arch), Self::Wasm(r) => r.default_modifier(arch), Self::Bpf(r) => r.default_modifier(arch), @@ -501,7 +501,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.supported_types(arch), Self::Hexagon(r) => r.supported_types(arch), Self::Mips(r) => r.supported_types(arch), - Self::s390x(r) => r.supported_types(arch), + Self::S390x(r) => r.supported_types(arch), Self::SpirV(r) => r.supported_types(arch), Self::Wasm(r) => r.supported_types(arch), Self::Bpf(r) => r.supported_types(arch), @@ -527,7 +527,7 @@ impl InlineAsmRegClass { InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?) } - InlineAsmArch::s390x => Self::s390x(s390xInlineAsmRegClass::parse(arch, name)?), + InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(arch, name)?), InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?), InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?), InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(arch, name)?), @@ -546,7 +546,7 @@ impl InlineAsmRegClass { Self::PowerPC(r) => r.valid_modifiers(arch), Self::Hexagon(r) => r.valid_modifiers(arch), Self::Mips(r) => r.valid_modifiers(arch), - Self::s390x(r) => r.valid_modifiers(arch), + Self::S390x(r) => r.valid_modifiers(arch), Self::SpirV(r) => r.valid_modifiers(arch), Self::Wasm(r) => r.valid_modifiers(arch), Self::Bpf(r) => r.valid_modifiers(arch), @@ -715,11 +715,11 @@ pub fn allocatable_registers( mips::fill_reg_map(arch, has_feature, target, &mut map); map } - InlineAsmArch::s390x => { - let mut map = s390x::regclass_map(); + InlineAsmArch::S390x => { + let mut map = s390x::regclass_map(); s390x::fill_reg_map(arch, has_feature, target, &mut map); map - } + } InlineAsmArch::SpirV => { let mut map = spirv::regclass_map(); spirv::fill_reg_map(arch, has_feature, target, &mut map); diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index ad07e20de8a02..0acbea800930c 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -3,13 +3,13 @@ use rustc_macros::HashStable_Generic; use std::fmt; def_reg_class! { - s390x s390xInlineAsmRegClass { + S390x S390xInlineAsmRegClass { reg, freg, } } -impl s390xInlineAsmRegClass { +impl S390xInlineAsmRegClass { pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] { &[] } @@ -42,8 +42,8 @@ impl s390xInlineAsmRegClass { } def_regs! { - s390x s390xInlineAsmReg s390xInlineAsmRegClass { - r0: req = ["r0"], + S390x S390xInlineAsmReg S390xInlineAsmRegClass { + r0: reg = ["r0"], r1: reg = ["r1"], r2: reg = ["r2"], r3: reg = ["r3"], @@ -144,7 +144,7 @@ def_regs! { } } -impl s390xInlineAsmReg { +impl S390xInlineAsmReg { pub fn emit( self, out: &mut dyn fmt::Write, diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs new file mode 100644 index 0000000000000..5f1a5f2de56be --- /dev/null +++ b/src/test/assembly/asm/s390x-types.rs @@ -0,0 +1,86 @@ +// min-llvm-version: 10.0.1 +// revisions: s390x +// assembly-output: emit-asm +//[s390x] compile-flags: --target s390x-unknown-linux-gnu +//[s390x] needs-llvm-components: systemz + +#![feature(no_core, lang_items, rustc_attrs, repr_simd)] +#![crate_type = "rlib"] +#![no_core] +#![allow(asm_sub_register, non_camel_case_types)] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} +#[rustc_builtin_macro] +macro_rules! concat { + () => {}; +} +#[rustc_builtin_macro] +macro_rules! stringify { + () => {}; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +type ptr = *const i32; + +impl Copy for i8 {} +impl Copy for u8 {} +impl Copy for i16 {} +impl Copy for i32 {} +impl Copy for i64 {} +impl Copy for f32 {} +impl Copy for f64 {} +impl Copy for ptr {} + +extern "C" { + fn extern_func(); + static extern_static: u8; +} + +// Hack to avoid function merging +extern "Rust" { + fn dont_merge(s: &str); +} + +macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { + + pub unsafe fn $func(x: $ty) -> $ty { + dont_merge(stringify!(func)); + + let y; + asm!(concat!($mov," {}, {}"), out($class) y, in($class) x); + y + } +};} + +macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { + + pub unsafe fn $func(x: $ty) -> $ty { + dont_merge(stringify!(func)); + + let y; + asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x); + y + } +};} + +// systemz-LABEL: sym_fn_32: +// systemz: #APP +// systemz: brasl %r14, extern_func@PLT +// systemz: #NO_APP +#[cfg(s390x)] +pub unsafe fn sym_fn_32() { + asm!("brasl %r14, {}", sym extern_func); +} + +// CHECK-LABEL: reg_i32: +// CHECK: #APP +// CHECK: lgr r{{[0-15]+}}, r{{[0-15]+}} +// CHECK: #NO_APP +check!(reg_i32, i32, reg, "lgr"); From 7095dfffc3bde0fc56a837241db84e414e3d9b25 Mon Sep 17 00:00:00 2001 From: linux1 Date: Wed, 18 Aug 2021 12:14:26 -0400 Subject: [PATCH 10/32] Refactor: added #[no_mangle] --- src/test/assembly/asm/s390x-types.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs index 5f1a5f2de56be..7b2ef9bda3478 100644 --- a/src/test/assembly/asm/s390x-types.rs +++ b/src/test/assembly/asm/s390x-types.rs @@ -75,6 +75,7 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { // systemz: brasl %r14, extern_func@PLT // systemz: #NO_APP #[cfg(s390x)] +#[no_mangle] pub unsafe fn sym_fn_32() { asm!("brasl %r14, {}", sym extern_func); } @@ -83,4 +84,5 @@ pub unsafe fn sym_fn_32() { // CHECK: #APP // CHECK: lgr r{{[0-15]+}}, r{{[0-15]+}} // CHECK: #NO_APP +#[no_mangle] check!(reg_i32, i32, reg, "lgr"); From 66e95b17ecfc93e39b1846436a86f0e924ab30b3 Mon Sep 17 00:00:00 2001 From: linux1 Date: Wed, 18 Aug 2021 12:40:18 -0400 Subject: [PATCH 11/32] Fix: moved #[no_mangle] --- src/test/assembly/asm/s390x-types.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs index 7b2ef9bda3478..0fbb77b96175e 100644 --- a/src/test/assembly/asm/s390x-types.rs +++ b/src/test/assembly/asm/s390x-types.rs @@ -49,7 +49,7 @@ extern "Rust" { } macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { - + #[no_mangle] pub unsafe fn $func(x: $ty) -> $ty { dont_merge(stringify!(func)); @@ -75,7 +75,6 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { // systemz: brasl %r14, extern_func@PLT // systemz: #NO_APP #[cfg(s390x)] -#[no_mangle] pub unsafe fn sym_fn_32() { asm!("brasl %r14, {}", sym extern_func); } @@ -84,5 +83,4 @@ pub unsafe fn sym_fn_32() { // CHECK: #APP // CHECK: lgr r{{[0-15]+}}, r{{[0-15]+}} // CHECK: #NO_APP -#[no_mangle] check!(reg_i32, i32, reg, "lgr"); From eeb0b52bf852b902b2bd1adaf919c35e2387ce28 Mon Sep 17 00:00:00 2001 From: linux1 Date: Sun, 22 Aug 2021 17:26:18 -0400 Subject: [PATCH 12/32] Feat: further testing & support for i64 general register use --- compiler/rustc_target/src/asm/s390x.rs | 2 +- src/test/assembly/asm/s390x-types.rs | 52 +++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index 0acbea800930c..dbf4168e4a80f 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -35,7 +35,7 @@ impl S390xInlineAsmRegClass { arch: InlineAsmArch, ) -> &'static [(InlineAsmType, Option<&'static str>)] { match (self, arch) { - (Self::reg, _) => types! { _: I8, I16, I32; }, + (Self::reg, _) => types! { _: I8, I16, I32, I64; }, (Self::freg, _) => types! { _: F32, F64; }, } } diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs index 0fbb77b96175e..692193158405f 100644 --- a/src/test/assembly/asm/s390x-types.rs +++ b/src/test/assembly/asm/s390x-types.rs @@ -60,7 +60,7 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { };} macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { - + #[no_mangle] pub unsafe fn $func(x: $ty) -> $ty { dont_merge(stringify!(func)); @@ -70,17 +70,57 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { } };} -// systemz-LABEL: sym_fn_32: -// systemz: #APP -// systemz: brasl %r14, extern_func@PLT -// systemz: #NO_APP +// CHECK-LABEL: sym_fn_32: +// CHECK: #APP +// CHECK: brasl %r14, extern_func +// CHECK: #NO_APP #[cfg(s390x)] +#[no_mangle] pub unsafe fn sym_fn_32() { asm!("brasl %r14, {}", sym extern_func); } +// CHECK-LABEL: sym_static: +// CHECK: #APP +// CHECK: brasl %r14, extern_static +// CHECK: #NO_APP +#[no_mangle] +pub unsafe fn sym_static() { + asm!("brasl %r14, {}", sym extern_static); +} + +// CHECK-LABEL: reg_i8: +// CHECK: #APP +// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_i8, i8, reg, "lgr"); + +// CHECK-LABEL: reg_i16: +// CHECK: #APP +// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_i16, i16, reg, "lgr"); + // CHECK-LABEL: reg_i32: // CHECK: #APP -// CHECK: lgr r{{[0-15]+}}, r{{[0-15]+}} +// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} // CHECK: #NO_APP check!(reg_i32, i32, reg, "lgr"); + +// CHECK-LABEL: reg_i64: +// CHECK: #APP +// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_i64, i64, reg, "lgr"); + +// CHECK-LABEL: reg_f32: +// CHECK: #APP +// CHECK: ler %f{{[0-9]+}}, %f{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_f32, f32, freg, "ler"); + +// CHECK-LABEL: reg_f64: +// CHECK: #APP +// CHECK: ldr %f{{[0-9]+}}, %f{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_f64, f64, freg, "ldr"); From 0c9e23c7ce964438b107d064533b89f024e7ccf8 Mon Sep 17 00:00:00 2001 From: linux1 Date: Sun, 22 Aug 2021 17:38:22 -0400 Subject: [PATCH 13/32] Fix: appeased x.py test tidy --bless --- compiler/rustc_target/src/asm/mod.rs | 10 +++++----- compiler/rustc_target/src/asm/s390x.rs | 2 +- src/test/assembly/asm/s390x-types.rs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 015faa14e28af..3b3017e37c1f0 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -257,7 +257,7 @@ impl InlineAsmReg { Self::PowerPC(r) => r.name(), Self::Hexagon(r) => r.name(), Self::Mips(r) => r.name(), - Self::S390x(r) => r.name(), + Self::S390x(r) => r.name(), Self::Bpf(r) => r.name(), Self::Err => "", } @@ -312,7 +312,7 @@ impl InlineAsmReg { InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, &name)?) } - InlineAsmArch::S390x => { + InlineAsmArch::S390x => { Self::S390x(S390xInlineAsmReg::parse(arch, has_feature, target, &name)?) } InlineAsmArch::SpirV => { @@ -715,11 +715,11 @@ pub fn allocatable_registers( mips::fill_reg_map(arch, has_feature, target, &mut map); map } - InlineAsmArch::S390x => { - let mut map = s390x::regclass_map(); + InlineAsmArch::S390x => { + let mut map = s390x::regclass_map(); s390x::fill_reg_map(arch, has_feature, target, &mut map); map - } + } InlineAsmArch::SpirV => { let mut map = spirv::regclass_map(); spirv::fill_reg_map(arch, has_feature, target, &mut map); diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index dbf4168e4a80f..29f370928713b 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -113,7 +113,7 @@ def_regs! { "c14 is reserved by the kernel and cannot be used as an operand for inline asm", #error = ["c15"] => "c15 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["a2"] => + #error = ["a2"] => "a2 is not supported by LLVM and cannot be used as an operand for inline asm", #error = ["a3"] => "a3 is not supported by LLVM and cannot be used as an operand for inline asm", diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs index 692193158405f..dd8a256516e6f 100644 --- a/src/test/assembly/asm/s390x-types.rs +++ b/src/test/assembly/asm/s390x-types.rs @@ -49,7 +49,7 @@ extern "Rust" { } macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { - #[no_mangle] + #[no_mangle] pub unsafe fn $func(x: $ty) -> $ty { dont_merge(stringify!(func)); @@ -60,7 +60,7 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { };} macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { - #[no_mangle] + #[no_mangle] pub unsafe fn $func(x: $ty) -> $ty { dont_merge(stringify!(func)); From 820e2680ec2f7f5f1b42dc94374986d251a22aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 23 Aug 2021 23:31:01 +0200 Subject: [PATCH 14/32] handle ascription type op in NLL HRTB diagnostics Refactors the `type_op_ascribe_user_type` query into a version which accepts a span, and uses it in the nicer NLL HRTB bound region errors. --- .../diagnostics/bound_region_errors.rs | 42 ++++++++++++++-- compiler/rustc_traits/src/lib.rs | 2 +- compiler/rustc_traits/src/type_op.rs | 48 +++++++++++++------ 3 files changed, 72 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs index d0284dd030236..ac30093ba8260 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::traits::query::type_op; use rustc_trait_selection::traits::{SelectionContext, TraitEngineExt as _}; -use rustc_traits::type_op_prove_predicate_with_span; +use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_span}; use std::fmt; use std::rc::Rc; @@ -104,10 +104,11 @@ impl<'tcx, T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx> ToUniverseInfo<'t impl<'tcx> ToUniverseInfo<'tcx> for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>> { - fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { - // Ascribe user type isn't usually called on types that have different - // bound regions. - UniverseInfo::other() + fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { + UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(AscribeUserTypeQuery { + canonical_query: self, + base_universe, + }))) } } @@ -267,6 +268,37 @@ where } } +struct AscribeUserTypeQuery<'tcx> { + canonical_query: Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>, + base_universe: ty::UniverseIndex, +} + +impl TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { + fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests, + // and is only the fallback when the nice error fails. Consider improving this some more. + tcx.sess.struct_span_err(span, "higher-ranked lifetime error") + } + + fn base_universe(&self) -> ty::UniverseIndex { + self.base_universe + } + + fn nice_error( + &self, + tcx: TyCtxt<'tcx>, + span: Span, + placeholder_region: ty::Region<'tcx>, + error_region: Option>, + ) -> Option> { + tcx.infer_ctxt().enter_with_canonical(span, &self.canonical_query, |ref infcx, key, _| { + let mut fulfill_cx = >::new(tcx); + type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(span)).ok()?; + try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) + }) + } +} + fn try_extract_error_from_fulfill_cx<'tcx>( mut fulfill_cx: Box + 'tcx>, infcx: &InferCtxt<'_, 'tcx>, diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index 8dd7c5bdfaebc..48c46c3069328 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -19,7 +19,7 @@ mod normalize_erasing_regions; mod normalize_projection_ty; mod type_op; -pub use type_op::type_op_prove_predicate_with_span; +pub use type_op::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_span}; use rustc_middle::ty::query::Providers; diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index c2e0a9987858e..a76fb84261615 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -40,18 +40,28 @@ fn type_op_ascribe_user_type<'tcx>( canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { - let (param_env, AscribeUserType { mir_ty, def_id, user_substs }) = key.into_parts(); - - debug!( - "type_op_ascribe_user_type: mir_ty={:?} def_id={:?} user_substs={:?}", - mir_ty, def_id, user_substs - ); + type_op_ascribe_user_type_with_span(infcx, fulfill_cx, key, None) + }) +} - let mut cx = AscribeUserTypeCx { infcx, param_env, fulfill_cx }; - cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs)?; +/// The core of the `type_op_ascribe_user_type` query: for diagnostics purposes in NLL HRTB errors, +/// this query can be re-run to better track the span of the obligation cause, and improve the error +/// message. Do not call directly unless you're in that very specific context. +pub fn type_op_ascribe_user_type_with_span<'a, 'tcx: 'a>( + infcx: &'a InferCtxt<'a, 'tcx>, + fulfill_cx: &'a mut dyn TraitEngine<'tcx>, + key: ParamEnvAnd<'tcx, AscribeUserType<'tcx>>, + span: Option, +) -> Result<(), NoSolution> { + let (param_env, AscribeUserType { mir_ty, def_id, user_substs }) = key.into_parts(); + debug!( + "type_op_ascribe_user_type: mir_ty={:?} def_id={:?} user_substs={:?}", + mir_ty, def_id, user_substs + ); - Ok(()) - }) + let mut cx = AscribeUserTypeCx { infcx, param_env, fulfill_cx }; + cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs, span)?; + Ok(()) } struct AscribeUserTypeCx<'me, 'tcx> { @@ -85,10 +95,15 @@ impl AscribeUserTypeCx<'me, 'tcx> { Ok(()) } - fn prove_predicate(&mut self, predicate: Predicate<'tcx>) { + fn prove_predicate(&mut self, predicate: Predicate<'tcx>, span: Option) { + let cause = if let Some(span) = span { + ObligationCause::dummy_with_span(span) + } else { + ObligationCause::dummy() + }; self.fulfill_cx.register_predicate_obligation( self.infcx, - Obligation::new(ObligationCause::dummy(), self.param_env, predicate), + Obligation::new(cause, self.param_env, predicate), ); } @@ -108,6 +123,7 @@ impl AscribeUserTypeCx<'me, 'tcx> { mir_ty: Ty<'tcx>, def_id: DefId, user_substs: UserSubsts<'tcx>, + span: Option, ) -> Result<(), NoSolution> { let UserSubsts { user_self_ty, substs } = user_substs; let tcx = self.tcx(); @@ -129,7 +145,7 @@ impl AscribeUserTypeCx<'me, 'tcx> { debug!(?instantiated_predicates.predicates); for instantiated_predicate in instantiated_predicates.predicates { let instantiated_predicate = self.normalize(instantiated_predicate); - self.prove_predicate(instantiated_predicate); + self.prove_predicate(instantiated_predicate, span); } if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty { @@ -141,6 +157,7 @@ impl AscribeUserTypeCx<'me, 'tcx> { self.prove_predicate( ty::PredicateKind::WellFormed(impl_self_ty.into()).to_predicate(self.tcx()), + span, ); } @@ -155,7 +172,10 @@ impl AscribeUserTypeCx<'me, 'tcx> { // them? This would only be relevant if some input // type were ill-formed but did not appear in `ty`, // which...could happen with normalization... - self.prove_predicate(ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx())); + self.prove_predicate( + ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()), + span, + ); Ok(()) } } From 05cd587726b01415f50ab8def30ea07864298e13 Mon Sep 17 00:00:00 2001 From: linux1 Date: Mon, 23 Aug 2021 17:32:27 -0400 Subject: [PATCH 15/32] Refactor: disabled frame pointer; consolidated unsupported register errors; added register prefix --- compiler/rustc_target/src/asm/s390x.rs | 86 ++++++-------------------- 1 file changed, 18 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index 29f370928713b..5ed93c0c1a9ce 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -54,8 +54,8 @@ def_regs! { r8: reg = ["r8"], r9: reg = ["r9"], r10: reg = ["r10"], - r11: reg = ["r11"], r12: reg = ["r12"], + r13: reg = ["r13"], r14: reg = ["r14"], f0: freg = ["f0"], f1: freg = ["f1"], @@ -73,74 +73,24 @@ def_regs! { f13: freg = ["f13"], f14: freg = ["f14"], f15: freg = ["f15"], - #error = ["r13"] => - "The base pointer cannot be used as an operand for inline asm", + #error = ["r11"] => + "The frame pointer cannot be used as an operand for inline asm", #error = ["r15"] => "The stack pointer cannot be used as an operand for inline asm", - #error = ["a0"] => - "This pointer is reserved on s390x and cannot be used as an operand for inline asm", - #error = ["a1"] => - "This pointer is reserved on z/Arch and cannot be used as an operand for inline asm", - #error = ["c0"] => - "c0 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c1"] => - "c1 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c2"] => - "c2 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c3"] => - "c3 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c4"] => - "c4 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c5"] => - "c5 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c6"] => - "c6 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c7"] => - "c7 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c8"] => - "c8 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c9"] => - "c9 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c10"] => - "c10 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c11"] => - "c11 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c12"] => - "c12 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c13"] => - "c13 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c14"] => - "c14 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["c15"] => - "c15 is reserved by the kernel and cannot be used as an operand for inline asm", - #error = ["a2"] => - "a2 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a3"] => - "a3 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a4"] => - "a4 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a5"] => - "a5 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a6"] => - "a6 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a7"] => - "a7 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a8"] => - "a8 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a9"] => - "a9 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a10"] => - "a10 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a11"] => - "a11 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a12"] => - "a12 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a13"] => - "a13 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a14"] => - "a14 is not supported by LLVM and cannot be used as an operand for inline asm", - #error = ["a15"] => - "a15 is not supported by LLVM and cannot be used as an operand for inline asm", + #error = [ + "c0", "c1", "c2", "c3", + "c4", "c5", "c6", "c7", + "c8", "c9", "c10", "c11", + "c12", "c13", "c14", "c15" + ] => + "control registers are reserved by the kernel and cannot be used as operands for inline asm", + #error = [ + "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", + "a8", "a9", "a10", "a11", + "a12", "a13", "a14", "a15" + ] => + "access registers are not supported and cannot be used as operands for inline asm", } } @@ -151,6 +101,6 @@ impl S390xInlineAsmReg { _arch: InlineAsmArch, _modifier: Option, ) -> fmt::Result { - out.write_str(self.name()) + out.write_str(&format!("%{}", self.name())) } } From a9f623707b8dcaba260b547e1950a4679b3b40eb Mon Sep 17 00:00:00 2001 From: linux1 Date: Mon, 23 Aug 2021 17:56:04 -0400 Subject: [PATCH 16/32] Fix: made suggested change --- compiler/rustc_target/src/asm/s390x.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index 5ed93c0c1a9ce..a74873f17476e 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -101,6 +101,6 @@ impl S390xInlineAsmReg { _arch: InlineAsmArch, _modifier: Option, ) -> fmt::Result { - out.write_str(&format!("%{}", self.name())) + write!(out, "%{}", self.name()) } } From 7b0e564e7cd3bebea7c41165db42a7b15010d2cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 23 Aug 2021 23:34:04 +0200 Subject: [PATCH 17/32] Update NLL HRTB type ascription blessed expectations Some of these tests have reached parity with the migrate-mode output. --- src/test/ui/hrtb/due-to-where-clause.nll.stderr | 8 -------- src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr | 8 -------- src/test/ui/hrtb/hrtb-just-for-static.nll.stderr | 7 +++++-- src/test/ui/issues/issue-54302.nll.stderr | 8 -------- 4 files changed, 5 insertions(+), 26 deletions(-) delete mode 100644 src/test/ui/hrtb/due-to-where-clause.nll.stderr delete mode 100644 src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr delete mode 100644 src/test/ui/issues/issue-54302.nll.stderr diff --git a/src/test/ui/hrtb/due-to-where-clause.nll.stderr b/src/test/ui/hrtb/due-to-where-clause.nll.stderr deleted file mode 100644 index 90803a0adb01b..0000000000000 --- a/src/test/ui/hrtb/due-to-where-clause.nll.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: higher-ranked subtype error - --> $DIR/due-to-where-clause.rs:2:5 - | -LL | test::(&mut 42); - | ^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr deleted file mode 100644 index 4de35d70c30a3..0000000000000 --- a/src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: higher-ranked subtype error - --> $DIR/hrtb-cache-issue-54302.rs:19:5 - | -LL | assert_deserialize_owned::<&'static str>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr b/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr index a812282def9a8..17d59bb321a45 100644 --- a/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr +++ b/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr @@ -17,11 +17,14 @@ LL | want_hrtb::<&'a u32>() | = help: consider replacing `'a` with `'static` -error: higher-ranked subtype error +error: implementation of `Foo` is not general enough --> $DIR/hrtb-just-for-static.rs:30:5 | LL | want_hrtb::<&'a u32>() - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<&'0 isize>` would have to be implemented for the type `&u32`, for any lifetime `'0`... + = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-54302.nll.stderr b/src/test/ui/issues/issue-54302.nll.stderr deleted file mode 100644 index e68de0312824d..0000000000000 --- a/src/test/ui/issues/issue-54302.nll.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: higher-ranked subtype error - --> $DIR/issue-54302.rs:13:5 - | -LL | assert_deserialize_owned::<&'static str>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - From 96381d390d7362e06809ee624dba2cca1bc6776f Mon Sep 17 00:00:00 2001 From: linux1 Date: Mon, 23 Aug 2021 21:53:23 -0400 Subject: [PATCH 18/32] Fix: added necessary prefix --- src/test/assembly/asm/s390x-types.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs index dd8a256516e6f..ec0515b20bdfb 100644 --- a/src/test/assembly/asm/s390x-types.rs +++ b/src/test/assembly/asm/s390x-types.rs @@ -51,7 +51,7 @@ extern "Rust" { macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { #[no_mangle] pub unsafe fn $func(x: $ty) -> $ty { - dont_merge(stringify!(func)); + dont_merge(stringify!($func)); let y; asm!(concat!($mov," {}, {}"), out($class) y, in($class) x); @@ -62,7 +62,7 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { #[no_mangle] pub unsafe fn $func(x: $ty) -> $ty { - dont_merge(stringify!(func)); + dont_merge(stringify!($func)); let y; asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x); @@ -124,3 +124,9 @@ check!(reg_f32, f32, freg, "ler"); // CHECK: ldr %f{{[0-9]+}}, %f{{[0-9]+}} // CHECK: #NO_APP check!(reg_f64, f64, freg, "ldr"); + +// CHECK-LABEL: reg_ptr: +// CHECK: #APP +// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_ptr, ptr, reg, "lgr"); From 07d37299eb898a4035a73cdabf731e14ccf9e140 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 23 Aug 2021 19:16:44 -0700 Subject: [PATCH 19/32] Update cargo --- Cargo.lock | 4 ++-- src/tools/cargo | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e0624c57ae94..424172f500382 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -871,9 +871,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.44+curl-7.77.0" +version = "0.4.45+curl-7.78.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6d85e9322b193f117c966e79c2d6929ec08c02f339f950044aba12e20bbaf1" +checksum = "de9e5a72b1c744eb5dd20b2be4d7eb84625070bb5c4ab9b347b70464ab1e62eb" dependencies = [ "cc", "libc", diff --git a/src/tools/cargo b/src/tools/cargo index e96bdb0c3d0a4..9b81660b79832 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit e96bdb0c3d0a418e7fcd7fbd69be08abf830b4bc +Subproject commit 9b81660b79832f92512edd4c29059a9ff88fcb6c From 4d8d72f4f9cd971fce3965015d785ecedb256326 Mon Sep 17 00:00:00 2001 From: Roxane Date: Mon, 23 Aug 2021 22:41:03 -0400 Subject: [PATCH 20/32] Handle match with non axhaustive variants in closures --- compiler/rustc_typeck/src/expr_use_visitor.rs | 17 +++++- .../auxiliary/match_non_exhaustive_lib.rs | 10 ++++ .../non-exhaustive-match.rs | 54 +++++++++++++++++++ .../non-exhaustive-match.stderr | 50 +++++++++++++++++ 4 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 1d7852d964c1d..c5c758255f0aa 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -14,7 +14,7 @@ use rustc_index::vec::Idx; use rustc_infer::infer::InferCtxt; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; -use rustc_middle::ty::{self, adjustment, TyCtxt}; +use rustc_middle::ty::{self, adjustment, AdtKind, TyCtxt}; use rustc_target::abi::VariantIdx; use std::iter; @@ -262,7 +262,20 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { let place_ty = place.place.ty(); if let ty::Adt(def, _) = place_ty.kind() { - if def.variants.len() > 1 { + // Note that if a non-exhaustive SingleVariant is defined in another crate, we need + // to assume that more cases will be added to the variant in the future. This mean + // that we should handle non-exhaustive SingleVariant the same way we would handle + // a MultiVariant. + // If the variant is not local it must be defined in another crate. + let is_non_exhaustive = match def.adt_kind() { + AdtKind::Struct | AdtKind::Union => { + def.non_enum_variant().is_field_list_non_exhaustive() + } + AdtKind::Enum => def.is_variant_list_non_exhaustive(), + }; + if def.variants.len() > 1 + || (!def.did.is_local() && is_non_exhaustive) + { needs_to_be_read = true; } } diff --git a/src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs b/src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs new file mode 100644 index 0000000000000..4060c409355a1 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs @@ -0,0 +1,10 @@ +#[non_exhaustive] +pub enum E1 {} + +#[non_exhaustive] +pub enum E2 { A, B } + +#[non_exhaustive] +pub enum E3 { C } + +pub enum E4 { D } diff --git a/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs b/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs new file mode 100644 index 0000000000000..318673ef847e5 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs @@ -0,0 +1,54 @@ +// edition:2021 + +// aux-build:match_non_exhaustive_lib.rs + +/* The error message for non-exhaustive matches on non-local enums + * marked as non-exhaustive should mention the fact that the enum + * is marked as non-exhaustive (issue #85227). + */ + +// Ignore non_exhaustive in the same crate +#[non_exhaustive] +enum L1 { A, B } +enum L2 { C } + +extern crate match_non_exhaustive_lib; +use match_non_exhaustive_lib::{E1, E2, E3, E4}; + +fn foo() -> (L1, L2) {todo!()} +fn bar() -> (E1, E2, E3, E4) {todo!()} + +fn main() { + let (l1, l2) = foo(); + // No error for enums defined in this crate + let _a = || { match l1 { L1::A => (), L1::B => () } }; + // (except if the match is already non-exhaustive) + let _b = || { match l1 { L1::A => () } }; + //~^ ERROR: non-exhaustive patterns: `B` not covered [E0004] + + // l2 should not be captured as it is a non-exhaustive SingleVariant + // defined in this crate + let _c = || { match l2 { L2::C => (), _ => () } }; + let mut mut_l2 = l2; + _c(); + + // E1 is not visibly uninhabited from here + let (e1, e2, e3, e4) = bar(); + let _d = || { match e1 {} }; + //~^ ERROR: non-exhaustive patterns: type `E1` is non-empty [E0004] + let _e = || { match e2 { E2::A => (), E2::B => () } }; + //~^ ERROR: non-exhaustive patterns: `_` not covered [E0004] + let _f = || { match e2 { E2::A => (), E2::B => (), _ => () } }; + + // e3 should be captured as it is a non-exhaustive SingleVariant + // defined in another crate + let _g = || { match e3 { E3::C => (), _ => () } }; + let mut mut_e3 = e3; + //~^ ERROR: cannot move out of `e3` because it is borrowed + _g(); + + // e4 should not be captured as it is a SingleVariant + let _h = || { match e4 { E4::D => (), _ => () } }; + let mut mut_e4 = e4; + _h(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr b/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr new file mode 100644 index 0000000000000..91ffe1a47f413 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr @@ -0,0 +1,50 @@ +error[E0004]: non-exhaustive patterns: `B` not covered + --> $DIR/non-exhaustive-match.rs:26:25 + | +LL | enum L1 { A, B } + | ---------------- + | | | + | | not covered + | `L1` defined here +... +LL | let _b = || { match l1 { L1::A => () } }; + | ^^ pattern `B` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `L1` + +error[E0004]: non-exhaustive patterns: type `E1` is non-empty + --> $DIR/non-exhaustive-match.rs:37:25 + | +LL | let _d = || { match e1 {} }; + | ^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `E1`, which is marked as non-exhaustive + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/non-exhaustive-match.rs:39:25 + | +LL | let _e = || { match e2 { E2::A => (), E2::B => () } }; + | ^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `E2`, which is marked as non-exhaustive + +error[E0505]: cannot move out of `e3` because it is borrowed + --> $DIR/non-exhaustive-match.rs:46:22 + | +LL | let _g = || { match e3 { E3::C => (), _ => () } }; + | -- -- borrow occurs due to use in closure + | | + | borrow of `e3` occurs here +LL | let mut mut_e3 = e3; + | ^^ move out of `e3` occurs here +LL | +LL | _g(); + | -- borrow later used here + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0004, E0505. +For more information about an error, try `rustc --explain E0004`. From 1335b4cadd66b026be809bbc07f77eb477393043 Mon Sep 17 00:00:00 2001 From: Roxane Date: Mon, 23 Aug 2021 22:41:19 -0400 Subject: [PATCH 21/32] Add additional match test case --- .../2229_closure_analysis/match-edge-cases.rs | 35 +++++++++++++++++++ .../match-edge-cases.stderr | 17 +++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr diff --git a/src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs b/src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs new file mode 100644 index 0000000000000..035c658302745 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs @@ -0,0 +1,35 @@ +// edition:2021 + +enum SingleVariant { + A +} + +struct TestStruct { + x: i32, + y: i32, + z: i32, +} + +fn main() { + let sv = SingleVariant::A; + let condition = true; + // sv should not be captured as it is a SingleVariant + let _a = || { + match sv { + SingleVariant::A if condition => (), + _ => () + } + }; + let mut mut_sv = sv; + _a(); + + // ts should be captured + let ts = TestStruct { x: 1, y: 1, z: 1 }; + let _b = || { match ts { + TestStruct{ x: 1, .. } => (), + _ => () + }}; + let mut mut_ts = ts; + //~^ ERROR: cannot move out of `ts` because it is borrowed + _b(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr b/src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr new file mode 100644 index 0000000000000..b9d2316206ecb --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr @@ -0,0 +1,17 @@ +error[E0505]: cannot move out of `ts` because it is borrowed + --> $DIR/match-edge-cases.rs:32:22 + | +LL | let _b = || { match ts { + | -- -- borrow occurs due to use in closure + | | + | borrow of `ts` occurs here +... +LL | let mut mut_ts = ts; + | ^^ move out of `ts` occurs here +LL | +LL | _b(); + | -- borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0505`. From 68b1bfc9b2d93d778b61c63b6a22847c128fc964 Mon Sep 17 00:00:00 2001 From: Roxane Date: Mon, 23 Aug 2021 22:57:05 -0400 Subject: [PATCH 22/32] Create a specific match folder for match tests --- .../{ => match}/auxiliary/match_non_exhaustive_lib.rs | 0 .../ui/closures/2229_closure_analysis/{ => match}/issue-87097.rs | 0 .../closures/2229_closure_analysis/{ => match}/issue-87097.stderr | 0 .../ui/closures/2229_closure_analysis/{ => match}/issue-87426.rs | 0 .../2229_closure_analysis/{ => match}/match-edge-cases.rs | 0 .../2229_closure_analysis/{ => match}/match-edge-cases.stderr | 0 .../2229_closure_analysis/{ => match}/non-exhaustive-match.rs | 0 .../2229_closure_analysis/{ => match}/non-exhaustive-match.stderr | 0 .../{ => match}/pattern-matching-should-fail.rs | 0 .../{ => match}/pattern-matching-should-fail.stderr | 0 .../{ => match}/patterns-capture-analysis.rs | 0 .../{ => match}/patterns-capture-analysis.stderr | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/closures/2229_closure_analysis/{ => match}/auxiliary/match_non_exhaustive_lib.rs (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/issue-87097.rs (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/issue-87097.stderr (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/issue-87426.rs (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/match-edge-cases.rs (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/match-edge-cases.stderr (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/non-exhaustive-match.rs (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/non-exhaustive-match.stderr (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/pattern-matching-should-fail.rs (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/pattern-matching-should-fail.stderr (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/patterns-capture-analysis.rs (100%) rename src/test/ui/closures/2229_closure_analysis/{ => match}/patterns-capture-analysis.stderr (100%) diff --git a/src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs b/src/test/ui/closures/2229_closure_analysis/match/auxiliary/match_non_exhaustive_lib.rs similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs rename to src/test/ui/closures/2229_closure_analysis/match/auxiliary/match_non_exhaustive_lib.rs diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87097.rs b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.rs similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/issue-87097.rs rename to src/test/ui/closures/2229_closure_analysis/match/issue-87097.rs diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87097.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/issue-87097.stderr rename to src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87426.rs b/src/test/ui/closures/2229_closure_analysis/match/issue-87426.rs similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/issue-87426.rs rename to src/test/ui/closures/2229_closure_analysis/match/issue-87426.rs diff --git a/src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases.rs similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs rename to src/test/ui/closures/2229_closure_analysis/match/match-edge-cases.rs diff --git a/src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases.stderr similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr rename to src/test/ui/closures/2229_closure_analysis/match/match-edge-cases.stderr diff --git a/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs rename to src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs diff --git a/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr rename to src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr diff --git a/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.rs b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.rs rename to src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs diff --git a/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.stderr b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.stderr rename to src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr diff --git a/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.rs b/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.rs rename to src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs diff --git a/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.stderr b/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr similarity index 100% rename from src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.stderr rename to src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr From 4a9ba65ca9eaf9db3a010cbf5859b3fdf16ac687 Mon Sep 17 00:00:00 2001 From: linux1 Date: Tue, 24 Aug 2021 12:41:49 -0400 Subject: [PATCH 23/32] Feat: added explicit register tests; added prefix to check_reg asm string --- src/test/assembly/asm/s390x-types.rs | 38 +++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs index ec0515b20bdfb..69d9cab23c8ed 100644 --- a/src/test/assembly/asm/s390x-types.rs +++ b/src/test/assembly/asm/s390x-types.rs @@ -65,7 +65,7 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { dont_merge(stringify!($func)); let y; - asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x); + asm!(concat!($mov, " %", $reg, ", %", $reg), lateout($reg) y, in($reg) x); y } };} @@ -130,3 +130,39 @@ check!(reg_f64, f64, freg, "ldr"); // CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} // CHECK: #NO_APP check!(reg_ptr, ptr, reg, "lgr"); + +// CHECK-LABEL: r0_i8: +// CHECK: #APP +// CHECK: lr %r0, %r0 +// CHECK: #NO_APP +check_reg!(r0_i8, i8, "r0", "lr"); + +// CHECK-LABEL: r0_i16: +// CHECK: #APP +// CHECK: lr %r0, %r0 +// CHECK: #NO_APP +check_reg!(r0_i16, i16, "r0", "lr"); + +// CHECK-LABEL: r0_i32: +// CHECK: #APP +// CHECK: lr %r0, %r0 +// CHECK: #NO_APP +check_reg!(r0_i32, i32, "r0", "lr"); + +// CHECK-LABEL: r0_i64: +// CHECK: #APP +// CHECK: lr %r0, %r0 +// CHECK: #NO_APP +check_reg!(r0_i64, i64, "r0", "lr"); + +// CHECK-LABEL: f0_f32: +// CHECK: #APP +// CHECK: ler %f0, %f0 +// CHECK: #NO_APP +check_reg!(f0_f32, f32, "f0", "ler"); + +// CHECK-LABEL: f0_f64: +// CHECK: #APP +// CHECK: ldr %f0, %f0 +// CHECK: #NO_APP +check_reg!(f0_f64, f64, "f0", "ldr"); From a216d666ca535d3cfcc8839fd3cb3d5e483e2d7e Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Wed, 25 Aug 2021 03:52:24 -0400 Subject: [PATCH 24/32] type_implements_trait consider obligation failure on overflow --- compiler/rustc_trait_selection/src/infer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index ea074192d23b1..c55b379741ee6 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -117,7 +117,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { recursion_depth: 0, predicate: trait_ref.without_const().to_predicate(self.tcx), }; - self.evaluate_obligation_no_overflow(&obligation) + self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr) } } From d7d122faecfcde3c34ffaa1cfa3f81debb60be59 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 25 Aug 2021 11:39:35 -0400 Subject: [PATCH 25/32] update docs for `type_implements_trait` --- compiler/rustc_trait_selection/src/infer.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index c55b379741ee6..3e79545d725e7 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -44,6 +44,10 @@ pub trait InferCtxtExt<'tcx> { /// - the self type /// - the *other* type parameters of the trait, excluding the self-type /// - the parameter environment + /// + /// Invokes `evaluate_obligation`, so in the event that evaluating + /// `Ty: Trait` causes overflow, EvaluatedToRecur (or EvaluatedToUnknown) + /// will be returned. fn type_implements_trait( &self, trait_def_id: DefId, From 88bcd4457be4d37d83d505ad3fe2dc7a5ce7203a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 25 Aug 2021 12:09:48 -0400 Subject: [PATCH 26/32] trailing whitespace --- compiler/rustc_trait_selection/src/infer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 3e79545d725e7..c90649353e80f 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -46,7 +46,7 @@ pub trait InferCtxtExt<'tcx> { /// - the parameter environment /// /// Invokes `evaluate_obligation`, so in the event that evaluating - /// `Ty: Trait` causes overflow, EvaluatedToRecur (or EvaluatedToUnknown) + /// `Ty: Trait` causes overflow, EvaluatedToRecur (or EvaluatedToUnknown) /// will be returned. fn type_implements_trait( &self, From 33c71ac87d4c4bad82dfd646d7a9254c6b358a26 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 25 Aug 2021 11:25:26 -0700 Subject: [PATCH 27/32] Add `c_size_t` and `c_ssize_t` to `std::os::raw`. --- library/std/src/os/raw/mod.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs index 50464a050c706..7ce58fb1d0ff7 100644 --- a/library/std/src/os/raw/mod.rs +++ b/library/std/src/os/raw/mod.rs @@ -151,3 +151,17 @@ type_alias_no_nz! { "double.md", c_double = f64; } #[stable(feature = "raw_os", since = "1.1.0")] #[doc(no_inline)] pub use core::ffi::c_void; + +/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++). +/// +/// This type is currently always [`usize`], however in the future there may be +/// platforms where this is not the case. +#[unstable(feature = "c_size_t", issue = "none")] +pub type c_size_t = usize; + +/// Equivalent to C's `ssize_t` type, from `stddef.h` (or `cstddef` for C++). +/// +/// This type is currently always [`isize`], however in the future there may be +/// platforms where this is not the case. +#[unstable(feature = "c_size_t", issue = "none")] +pub type c_ssize_t = isize; From 8a6501d28831d864a3af6adf2e0bd83a773062ed Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 25 Aug 2021 14:40:06 -0700 Subject: [PATCH 28/32] Adjust spans * Highlight the whole pattern if it has no fields * Highlight the whole definition if it has no fields * Only highlight the pattern name if the pattern is multi-line * Determine whether a pattern is multi-line based on distance from name to last field, rather than first field --- compiler/rustc_typeck/src/check/pat.rs | 10 +- .../tuple_struct_destructure_fail.stderr | 8 +- src/test/ui/error-codes/E0023.stderr | 12 +- src/test/ui/issues/issue-72574-2.stderr | 2 +- .../match/match-pattern-field-mismatch.stderr | 2 +- ...7-pat-tup-scrut-ty-diff-less-fields.stderr | 4 +- src/test/ui/pattern/issue-74539.stderr | 2 +- .../pat-tuple-field-count-cross.stderr | 54 ++++----- src/test/ui/pattern/pat-tuple-overfield.rs | 16 +++ .../ui/pattern/pat-tuple-overfield.stderr | 108 ++++++++++++++---- src/test/ui/pattern/pat-tuple-underfield.rs | 12 ++ .../ui/pattern/pat-tuple-underfield.stderr | 64 ++++++++--- .../ui/pattern/pattern-error-continue.stderr | 2 +- 13 files changed, 211 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 341385731e7d2..e1f0d3c436366 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -992,7 +992,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let fields_ending = pluralize!(fields.len()); let subpat_spans = if subpats.is_empty() { - vec![pat_span.trim_start(qpath.span()).unwrap_or(pat_span)] + vec![pat_span] } else { subpats.iter().map(|p| p.span).collect() }; @@ -1000,7 +1000,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let res_span = self.tcx.def_span(res.def_id()); let def_ident_span = self.tcx.def_ident_span(res.def_id()).unwrap_or(res_span); let field_def_spans = if fields.is_empty() { - vec![res_span.trim_start(def_ident_span).unwrap_or(res_span)] + vec![res_span] } else { fields.iter().map(|f| f.ident.span).collect() }; @@ -1021,8 +1021,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { last_subpat_span, &format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len()), ); - err.span_label(qpath.span(), ""); - if self.tcx.sess.source_map().is_multiline(def_ident_span.between(field_def_spans[0])) { + if self.tcx.sess.source_map().is_multiline(qpath.span().between(last_subpat_span)) { + err.span_label(qpath.span(), ""); + } + if self.tcx.sess.source_map().is_multiline(def_ident_span.between(last_field_def_span)) { err.span_label(def_ident_span, format!("{} defined here", res.descr())); } for span in &field_def_spans[..field_def_spans.len() - 1] { diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr index 9a47ddf047991..9aae4b0a3faed 100644 --- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr +++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr @@ -21,7 +21,7 @@ LL | struct TupleStruct(S, T); | - - tuple struct has 2 fields ... LL | TupleStruct(a, a, b) = TupleStruct(1, 2); - | ----------- ^ ^ ^ expected 2 fields, found 3 + | ^ ^ ^ expected 2 fields, found 3 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields --> $DIR/tuple_struct_destructure_fail.rs:32:17 @@ -30,7 +30,7 @@ LL | struct TupleStruct(S, T); | - - tuple struct has 2 fields ... LL | TupleStruct(_) = TupleStruct(1, 2); - | ----------- ^ expected 2 fields, found 1 + | ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -48,7 +48,7 @@ LL | SingleVariant(S, T) | - - tuple variant has 2 fields ... LL | Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2); - | ------------------- ^ ^ ^ expected 2 fields, found 3 + | ^ ^ ^ expected 2 fields, found 3 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields --> $DIR/tuple_struct_destructure_fail.rs:36:25 @@ -57,7 +57,7 @@ LL | SingleVariant(S, T) | - - tuple variant has 2 fields ... LL | Enum::SingleVariant(_) = Enum::SingleVariant(1, 2); - | ------------------- ^ expected 2 fields, found 1 + | ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr index 85e1b2cb4ceef..3e321b037b2b2 100644 --- a/src/test/ui/error-codes/E0023.stderr +++ b/src/test/ui/error-codes/E0023.stderr @@ -5,7 +5,7 @@ LL | Apple(String, String), | ------ ------ tuple variant has 2 fields ... LL | Fruit::Apple(a) => {}, - | ------------ ^ expected 2 fields, found 1 + | ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -19,7 +19,7 @@ LL | Apple(String, String), | ------ ------ tuple variant has 2 fields ... LL | Fruit::Apple(a, b, c) => {}, - | ------------ ^ ^ ^ expected 2 fields, found 3 + | ^ ^ ^ expected 2 fields, found 3 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field --> $DIR/E0023.rs:13:21 @@ -28,7 +28,7 @@ LL | Pear(u32), | --- tuple variant has 1 field ... LL | Fruit::Pear(1, 2) => {}, - | ----------- ^ ^ expected 1 field, found 2 + | ^ ^ expected 1 field, found 2 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field --> $DIR/E0023.rs:14:23 @@ -37,7 +37,7 @@ LL | Orange((String, String)), | ---------------- tuple variant has 1 field ... LL | Fruit::Orange(a, b) => {}, - | ------------- ^ ^ expected 1 field, found 2 + | ^ ^ expected 1 field, found 2 | help: missing parentheses | @@ -45,13 +45,13 @@ LL | Fruit::Orange((a, b)) => {}, | + + error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 1 field - --> $DIR/E0023.rs:15:22 + --> $DIR/E0023.rs:15:9 | LL | Banana(()), | -- tuple variant has 1 field ... LL | Fruit::Banana() => {}, - | -------------^^ expected 1 field, found 0 + | ^^^^^^^^^^^^^^^ expected 1 field, found 0 | help: missing parentheses | diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr index 3f8ff4f0bacd5..05650f05cbf5b 100644 --- a/src/test/ui/issues/issue-72574-2.stderr +++ b/src/test/ui/issues/issue-72574-2.stderr @@ -25,7 +25,7 @@ LL | struct Binder(i32, i32, i32); | --- --- --- tuple struct has 3 fields ... LL | Binder(_a, _x @ ..) => {} - | ------ ^^ ^^^^^^^ expected 3 fields, found 2 + | ^^ ^^^^^^^ expected 3 fields, found 2 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr index 01d7cf0d054c9..c994ee4f6d4ff 100644 --- a/src/test/ui/match/match-pattern-field-mismatch.stderr +++ b/src/test/ui/match/match-pattern-field-mismatch.stderr @@ -5,7 +5,7 @@ LL | Rgb(usize, usize, usize), | ----- ----- ----- tuple variant has 3 fields ... LL | Color::Rgb(_, _) => { } - | ---------- ^ ^ expected 3 fields, found 2 + | ^ ^ expected 3 fields, found 2 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr index c87b70625b40e..75a231f6b4ba3 100644 --- a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr +++ b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr @@ -10,13 +10,13 @@ LL | let P() = U {}; found struct `P<_>` error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 1 field - --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:10 + --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9 | LL | struct P(T); // 1 type parameter wanted | - tuple struct has 1 field ... LL | let P() = U {}; - | -^^ expected 1 field, found 0 + | ^^^ expected 1 field, found 0 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/issue-74539.stderr b/src/test/ui/pattern/issue-74539.stderr index d7cbcf2cfa109..7443946c013f7 100644 --- a/src/test/ui/pattern/issue-74539.stderr +++ b/src/test/ui/pattern/issue-74539.stderr @@ -25,7 +25,7 @@ LL | A(u8, u8), | -- -- tuple variant has 2 fields ... LL | E::A(x @ ..) => { - | ---- ^^^^^^ expected 2 fields, found 1 + | ^^^^^^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | diff --git a/src/test/ui/pattern/pat-tuple-field-count-cross.stderr b/src/test/ui/pattern/pat-tuple-field-count-cross.stderr index 570bf0cbc0810..cab8d4759df64 100644 --- a/src/test/ui/pattern/pat-tuple-field-count-cross.stderr +++ b/src/test/ui/pattern/pat-tuple-field-count-cross.stderr @@ -121,7 +121,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 --> $DIR/pat-tuple-field-count-cross.rs:14:12 | LL | Z1(x) => {} - | -- ^ expected 0 fields, found 1 + | ^ expected 0 fields, found 1 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:2:1 | @@ -129,10 +129,10 @@ LL | pub struct Z1(); | ---------------- tuple struct has 0 fields error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-field-count-cross.rs:18:10 + --> $DIR/pat-tuple-field-count-cross.rs:18:9 | LL | S() => {} - | -^^ expected 3 fields, found 0 + | ^^^ expected 3 fields, found 0 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14 | @@ -152,7 +152,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 --> $DIR/pat-tuple-field-count-cross.rs:19:11 | LL | S(1) => {} - | - ^ expected 3 fields, found 1 + | ^ expected 3 fields, found 1 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14 | @@ -172,7 +172,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has --> $DIR/pat-tuple-field-count-cross.rs:20:11 | LL | S(xyz, abc) => {} - | - ^^^ ^^^ expected 3 fields, found 2 + | ^^^ ^^^ expected 3 fields, found 2 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14 | @@ -188,7 +188,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has --> $DIR/pat-tuple-field-count-cross.rs:21:11 | LL | S(1, 2, 3, 4) => {} - | - ^ ^ ^ ^ expected 3 fields, found 4 + | ^ ^ ^ ^ expected 3 fields, found 4 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14 | @@ -196,10 +196,10 @@ LL | pub struct S(pub u8, pub u8, pub u8); | ------ ------ ------ tuple struct has 3 fields error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 3 fields - --> $DIR/pat-tuple-field-count-cross.rs:24:10 + --> $DIR/pat-tuple-field-count-cross.rs:24:9 | LL | M() => {} - | -^^ expected 3 fields, found 0 + | ^^^ expected 3 fields, found 0 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1 | @@ -226,7 +226,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 --> $DIR/pat-tuple-field-count-cross.rs:25:11 | LL | M(1) => {} - | - ^ expected 3 fields, found 1 + | ^ expected 3 fields, found 1 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1 | @@ -253,7 +253,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has --> $DIR/pat-tuple-field-count-cross.rs:26:11 | LL | M(xyz, abc) => {} - | - ^^^ ^^^ expected 3 fields, found 2 + | ^^^ ^^^ expected 3 fields, found 2 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1 | @@ -276,7 +276,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has --> $DIR/pat-tuple-field-count-cross.rs:27:11 | LL | M(1, 2, 3, 4) => {} - | - ^ ^ ^ ^ expected 3 fields, found 4 + | ^ ^ ^ ^ expected 3 fields, found 4 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1 | @@ -294,7 +294,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:36:16 | LL | E1::Z1(x) => {} - | ------ ^ expected 0 fields, found 1 + | ^ expected 0 fields, found 1 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19 | @@ -302,10 +302,10 @@ LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } | ---- tuple variant has 0 fields error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields - --> $DIR/pat-tuple-field-count-cross.rs:39:14 + --> $DIR/pat-tuple-field-count-cross.rs:39:9 | LL | E1::S() => {} - | -----^^ expected 3 fields, found 0 + | ^^^^^^^ expected 3 fields, found 0 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27 | @@ -325,7 +325,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:40:15 | LL | E1::S(1) => {} - | ----- ^ expected 3 fields, found 1 + | ^ expected 3 fields, found 1 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27 | @@ -345,7 +345,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:41:15 | LL | E1::S(xyz, abc) => {} - | ----- ^^^ ^^^ expected 3 fields, found 2 + | ^^^ ^^^ expected 3 fields, found 2 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27 | @@ -361,7 +361,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:42:15 | LL | E1::S(1, 2, 3, 4) => {} - | ----- ^ ^ ^ ^ expected 3 fields, found 4 + | ^ ^ ^ ^ expected 3 fields, found 4 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27 | @@ -369,10 +369,10 @@ LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } | -- -- -- tuple variant has 3 fields error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields - --> $DIR/pat-tuple-field-count-cross.rs:46:14 + --> $DIR/pat-tuple-field-count-cross.rs:46:9 | LL | E2::S() => {} - | -----^^ expected 3 fields, found 0 + | ^^^^^^^ expected 3 fields, found 0 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7 | @@ -392,7 +392,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:47:15 | LL | E2::S(1) => {} - | ----- ^ expected 3 fields, found 1 + | ^ expected 3 fields, found 1 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7 | @@ -412,7 +412,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:48:15 | LL | E2::S(xyz, abc) => {} - | ----- ^^^ ^^^ expected 3 fields, found 2 + | ^^^ ^^^ expected 3 fields, found 2 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7 | @@ -428,7 +428,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:49:15 | LL | E2::S(1, 2, 3, 4) => {} - | ----- ^ ^ ^ ^ expected 3 fields, found 4 + | ^ ^ ^ ^ expected 3 fields, found 4 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7 | @@ -436,10 +436,10 @@ LL | S(u8, u8, u8), | -- -- -- tuple variant has 3 fields error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields - --> $DIR/pat-tuple-field-count-cross.rs:52:14 + --> $DIR/pat-tuple-field-count-cross.rs:52:9 | LL | E2::M() => {} - | -----^^ expected 3 fields, found 0 + | ^^^^^^^ expected 3 fields, found 0 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5 | @@ -466,7 +466,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:53:15 | LL | E2::M(1) => {} - | ----- ^ expected 3 fields, found 1 + | ^ expected 3 fields, found 1 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5 | @@ -493,7 +493,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:54:15 | LL | E2::M(xyz, abc) => {} - | ----- ^^^ ^^^ expected 3 fields, found 2 + | ^^^ ^^^ expected 3 fields, found 2 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5 | @@ -516,7 +516,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has --> $DIR/pat-tuple-field-count-cross.rs:55:15 | LL | E2::M(1, 2, 3, 4) => {} - | ----- ^ ^ ^ ^ expected 3 fields, found 4 + | ^ ^ ^ ^ expected 3 fields, found 4 | ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5 | diff --git a/src/test/ui/pattern/pat-tuple-overfield.rs b/src/test/ui/pattern/pat-tuple-overfield.rs index dd0548a088c72..c863c657514f3 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.rs +++ b/src/test/ui/pattern/pat-tuple-overfield.rs @@ -30,6 +30,22 @@ fn main() { match M(1, 2, 3, 4, 5) { M(1, 2, 3, 4, 5, 6) => {} //~^ ERROR this pattern has 6 fields, but the corresponding tuple struct has 5 fields + M(1, + 2, + 3, + 4, + 5, + 6) => {} + //~^ ERROR this pattern has 6 fields, but the corresponding tuple struct has 5 fields + M( + 1, + 2, + 3, + 4, + 5, + 6, + ) => {} + //~^^ ERROR this pattern has 6 fields, but the corresponding tuple struct has 5 fields } match Z0 { Z0 => {} diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr index 646ac4e661897..1c44f7e5f6f1f 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.stderr +++ b/src/test/ui/pattern/pat-tuple-overfield.stderr @@ -1,5 +1,5 @@ error[E0530]: match bindings cannot shadow tuple structs - --> $DIR/pat-tuple-overfield.rs:41:9 + --> $DIR/pat-tuple-overfield.rs:57:9 | LL | struct Z1(); | ------------ the tuple struct `Z1` is defined here @@ -8,7 +8,7 @@ LL | Z1 => {} | ^^ cannot be named the same as a tuple struct error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` - --> $DIR/pat-tuple-overfield.rs:36:9 + --> $DIR/pat-tuple-overfield.rs:52:9 | LL | struct Z0; | ---------- `Z0` defined here @@ -28,7 +28,7 @@ LL | Z1() => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` - --> $DIR/pat-tuple-overfield.rs:37:9 + --> $DIR/pat-tuple-overfield.rs:53:9 | LL | struct Z0; | ---------- `Z0` defined here @@ -48,7 +48,7 @@ LL | Z1(_) => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0` - --> $DIR/pat-tuple-overfield.rs:38:9 + --> $DIR/pat-tuple-overfield.rs:54:9 | LL | struct Z0; | ---------- `Z0` defined here @@ -68,7 +68,7 @@ LL | Z1(_, _) => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` - --> $DIR/pat-tuple-overfield.rs:48:9 + --> $DIR/pat-tuple-overfield.rs:64:9 | LL | Z0, | -- `E1::Z0` defined here @@ -88,7 +88,7 @@ LL | E1::Z1() => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` - --> $DIR/pat-tuple-overfield.rs:49:9 + --> $DIR/pat-tuple-overfield.rs:65:9 | LL | Z0, | -- `E1::Z0` defined here @@ -108,7 +108,7 @@ LL | E1::Z1(_) => {} | ~~ error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0` - --> $DIR/pat-tuple-overfield.rs:50:9 + --> $DIR/pat-tuple-overfield.rs:66:9 | LL | Z0, | -- `E1::Z0` defined here @@ -128,7 +128,7 @@ LL | E1::Z1(_, _) => {} | ~~ error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1` - --> $DIR/pat-tuple-overfield.rs:53:9 + --> $DIR/pat-tuple-overfield.rs:69:9 | LL | Z0, | -- similarly named unit variant `Z0` defined here @@ -177,7 +177,7 @@ LL | struct S(u8, u8, u8); | -- -- -- tuple struct has 3 fields ... LL | S(1, 2, 3, 4) => {} - | - ^ ^ ^ ^ expected 3 fields, found 4 + | ^ ^ ^ ^ expected 3 fields, found 4 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields --> $DIR/pat-tuple-overfield.rs:26:11 @@ -186,7 +186,7 @@ LL | struct S(u8, u8, u8); | -- -- -- tuple struct has 3 fields ... LL | S(1, 2, .., 3, 4) => {} - | - ^ ^ ^ ^ expected 3 fields, found 4 + | ^ ^ ^ ^ expected 3 fields, found 4 error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields --> $DIR/pat-tuple-overfield.rs:31:11 @@ -205,45 +205,105 @@ LL | u8, | -- tuple struct has 5 fields ... LL | M(1, 2, 3, 4, 5, 6) => {} - | - ^ ^ ^ ^ ^ ^ expected 5 fields, found 6 + | ^ ^ ^ ^ ^ ^ expected 5 fields, found 6 + +error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields + --> $DIR/pat-tuple-overfield.rs:33:11 + | +LL | struct M( + | - tuple struct defined here +LL | u8, + | -- +LL | u8, + | -- +LL | u8, + | -- +LL | u8, + | -- +LL | u8, + | -- tuple struct has 5 fields +... +LL | M(1, + | - ^ +LL | 2, + | ^ +LL | 3, + | ^ +LL | 4, + | ^ +LL | 5, + | ^ +LL | 6) => {} + | ^ expected 5 fields, found 6 + +error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields + --> $DIR/pat-tuple-overfield.rs:41:13 + | +LL | struct M( + | - tuple struct defined here +LL | u8, + | -- +LL | u8, + | -- +LL | u8, + | -- +LL | u8, + | -- +LL | u8, + | -- tuple struct has 5 fields +... +LL | M( + | - +LL | 1, + | ^ +LL | 2, + | ^ +LL | 3, + | ^ +LL | 4, + | ^ +LL | 5, + | ^ +LL | 6, + | ^ expected 5 fields, found 6 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields - --> $DIR/pat-tuple-overfield.rs:43:12 + --> $DIR/pat-tuple-overfield.rs:59:12 | LL | struct Z1(); - | --- tuple struct has 0 fields + | ------------ tuple struct has 0 fields ... LL | Z1(_) => {} - | -- ^ expected 0 fields, found 1 + | ^ expected 0 fields, found 1 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 0 fields - --> $DIR/pat-tuple-overfield.rs:44:12 + --> $DIR/pat-tuple-overfield.rs:60:12 | LL | struct Z1(); - | --- tuple struct has 0 fields + | ------------ tuple struct has 0 fields ... LL | Z1(_, _) => {} - | -- ^ ^ expected 0 fields, found 2 + | ^ ^ expected 0 fields, found 2 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields - --> $DIR/pat-tuple-overfield.rs:55:16 + --> $DIR/pat-tuple-overfield.rs:71:16 | LL | Z1(), - | -- tuple variant has 0 fields + | ---- tuple variant has 0 fields ... LL | E1::Z1(_) => {} - | ------ ^ expected 0 fields, found 1 + | ^ expected 0 fields, found 1 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 0 fields - --> $DIR/pat-tuple-overfield.rs:56:16 + --> $DIR/pat-tuple-overfield.rs:72:16 | LL | Z1(), - | -- tuple variant has 0 fields + | ---- tuple variant has 0 fields ... LL | E1::Z1(_, _) => {} - | ------ ^ ^ expected 0 fields, found 2 + | ^ ^ expected 0 fields, found 2 -error: aborting due to 17 previous errors +error: aborting due to 19 previous errors Some errors have detailed explanations: E0023, E0308, E0530, E0532. For more information about an error, try `rustc --explain E0023`. diff --git a/src/test/ui/pattern/pat-tuple-underfield.rs b/src/test/ui/pattern/pat-tuple-underfield.rs index ed852a47bb4ee..dac60e3fab2c0 100644 --- a/src/test/ui/pattern/pat-tuple-underfield.rs +++ b/src/test/ui/pattern/pat-tuple-underfield.rs @@ -21,6 +21,12 @@ fn main() { //~^ ERROR this pattern has 0 fields, but the corresponding tuple struct has 2 fields //~| HELP use `_` to explicitly ignore each field //~| HELP use `..` to ignore all fields + + // Test non-standard formatting + S () => {} + //~^ ERROR this pattern has 0 fields, but the corresponding tuple struct has 2 fields + //~| HELP use `_` to explicitly ignore each field + //~| HELP use `..` to ignore all fields } match E::S(0, 1.0) { @@ -39,6 +45,12 @@ fn main() { //~^ ERROR this pattern has 0 fields, but the corresponding tuple variant has 2 fields //~| HELP use `_` to explicitly ignore each field //~| HELP use `..` to ignore all fields + + // Test non-standard formatting + E::S () => {} + //~^ ERROR this pattern has 0 fields, but the corresponding tuple variant has 2 fields + //~| HELP use `_` to explicitly ignore each field + //~| HELP use `..` to ignore all fields } match E::S(0, 1.0) { E::S => {} diff --git a/src/test/ui/pattern/pat-tuple-underfield.stderr b/src/test/ui/pattern/pat-tuple-underfield.stderr index 4c21ad0be3eb4..e75f9b38da566 100644 --- a/src/test/ui/pattern/pat-tuple-underfield.stderr +++ b/src/test/ui/pattern/pat-tuple-underfield.stderr @@ -1,5 +1,5 @@ error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E::S` - --> $DIR/pat-tuple-underfield.rs:44:9 + --> $DIR/pat-tuple-underfield.rs:56:9 | LL | S(i32, f32), | ----------- `E::S` defined here @@ -14,7 +14,7 @@ LL | struct S(i32, f32); | --- --- tuple struct has 2 fields ... LL | S(x) => {} - | - ^ expected 2 fields, found 1 + | ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -28,7 +28,7 @@ LL | struct S(i32, f32); | --- --- tuple struct has 2 fields ... LL | S(_) => {} - | - ^ expected 2 fields, found 1 + | ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -40,13 +40,13 @@ LL | S(..) => {} | ~~ error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 2 fields - --> $DIR/pat-tuple-underfield.rs:20:10 + --> $DIR/pat-tuple-underfield.rs:20:9 | LL | struct S(i32, f32); | --- --- tuple struct has 2 fields ... LL | S() => {} - | -^^ expected 2 fields, found 0 + | ^^^ expected 2 fields, found 0 | help: use `_` to explicitly ignore each field | @@ -57,14 +57,32 @@ help: use `..` to ignore all fields LL | S(..) => {} | ++ +error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 2 fields + --> $DIR/pat-tuple-underfield.rs:26:9 + | +LL | struct S(i32, f32); + | --- --- tuple struct has 2 fields +... +LL | S () => {} + | ^^^^ expected 2 fields, found 0 + | +help: use `_` to explicitly ignore each field + | +LL | S (_, _) => {} + | ++++ +help: use `..` to ignore all fields + | +LL | S (..) => {} + | ++ + error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/pat-tuple-underfield.rs:27:14 + --> $DIR/pat-tuple-underfield.rs:33:14 | LL | S(i32, f32), | --- --- tuple variant has 2 fields ... LL | E::S(x) => {} - | ---- ^ expected 2 fields, found 1 + | ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -72,13 +90,13 @@ LL | E::S(x, _) => {} | +++ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/pat-tuple-underfield.rs:32:14 + --> $DIR/pat-tuple-underfield.rs:38:14 | LL | S(i32, f32), | --- --- tuple variant has 2 fields ... LL | E::S(_) => {} - | ---- ^ expected 2 fields, found 1 + | ^ expected 2 fields, found 1 | help: use `_` to explicitly ignore each field | @@ -90,13 +108,13 @@ LL | E::S(..) => {} | ~~ error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 2 fields - --> $DIR/pat-tuple-underfield.rs:38:13 + --> $DIR/pat-tuple-underfield.rs:44:9 | LL | S(i32, f32), | --- --- tuple variant has 2 fields ... LL | E::S() => {} - | ----^^ expected 2 fields, found 0 + | ^^^^^^ expected 2 fields, found 0 | help: use `_` to explicitly ignore each field | @@ -107,14 +125,32 @@ help: use `..` to ignore all fields LL | E::S(..) => {} | ++ +error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 2 fields + --> $DIR/pat-tuple-underfield.rs:50:9 + | +LL | S(i32, f32), + | --- --- tuple variant has 2 fields +... +LL | E::S () => {} + | ^^^^^^^ expected 2 fields, found 0 + | +help: use `_` to explicitly ignore each field + | +LL | E::S (_, _) => {} + | ++++ +help: use `..` to ignore all fields + | +LL | E::S (..) => {} + | ++ + error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 4 fields - --> $DIR/pat-tuple-underfield.rs:50:19 + --> $DIR/pat-tuple-underfield.rs:62:19 | LL | struct Point4(i32, i32, i32, i32); | --- --- --- --- tuple struct has 4 fields ... LL | Point4( a , _ ) => {} - | ------ ^ ^ expected 4 fields, found 2 + | ^ ^ expected 4 fields, found 2 | help: use `_` to explicitly ignore each field | @@ -125,7 +161,7 @@ help: use `..` to ignore the rest of the fields LL | Point4( a, ..) => {} | ~~~~ -error: aborting due to 8 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0023, E0532. For more information about an error, try `rustc --explain E0023`. diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr index efc6723e9ef8e..c800afdae2afb 100644 --- a/src/test/ui/pattern/pattern-error-continue.stderr +++ b/src/test/ui/pattern/pattern-error-continue.stderr @@ -32,7 +32,7 @@ LL | B(isize, isize), | ----- ----- tuple variant has 2 fields ... LL | A::B(_, _, _) => (), - | ---- ^ ^ ^ expected 2 fields, found 3 + | ^ ^ ^ expected 2 fields, found 3 error[E0308]: mismatched types --> $DIR/pattern-error-continue.rs:22:9 From 5b25de58d6cbfab4fefe3200de8864ab8f6a71d1 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 25 Aug 2021 14:58:17 -0700 Subject: [PATCH 29/32] Reference tracking issue --- library/std/src/os/raw/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs index 7ce58fb1d0ff7..1e220ea30ab95 100644 --- a/library/std/src/os/raw/mod.rs +++ b/library/std/src/os/raw/mod.rs @@ -156,12 +156,12 @@ pub use core::ffi::c_void; /// /// This type is currently always [`usize`], however in the future there may be /// platforms where this is not the case. -#[unstable(feature = "c_size_t", issue = "none")] +#[unstable(feature = "c_size_t", issue = "88345")] pub type c_size_t = usize; /// Equivalent to C's `ssize_t` type, from `stddef.h` (or `cstddef` for C++). /// /// This type is currently always [`isize`], however in the future there may be /// platforms where this is not the case. -#[unstable(feature = "c_size_t", issue = "none")] +#[unstable(feature = "c_size_t", issue = "88345")] pub type c_ssize_t = isize; From 5df5659a6b96436ae55fd6bd8e9a7dbe7e22b37d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 25 Aug 2021 19:14:50 -0300 Subject: [PATCH 30/32] Revert "Add type of a let tait test impl trait straight in let" This reverts commit dbadab54df148b55b2e884440bfaeaa38517e6e8. This is not part of TAITs, so, if tested should probably be done elsewhere. --- .../type-alias-impl-trait/type_of_a_let2.rs | 25 ------------------- .../type_of_a_let2.stderr | 21 ---------------- 2 files changed, 46 deletions(-) delete mode 100644 src/test/ui/type-alias-impl-trait/type_of_a_let2.rs delete mode 100644 src/test/ui/type-alias-impl-trait/type_of_a_let2.stderr diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let2.rs b/src/test/ui/type-alias-impl-trait/type_of_a_let2.rs deleted file mode 100644 index 33d3f164ce15e..0000000000000 --- a/src/test/ui/type-alias-impl-trait/type_of_a_let2.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![feature(type_alias_impl_trait)] -#![allow(dead_code)] - -// FIXME This should be under a feature flag - -use std::fmt::Debug; - -fn foo1() -> u32 { - let x: impl Debug = 22_u32; - //~^ ERROR: `impl Trait` not allowed outside of function and method return types [E0562] - x // ERROR: we only know x: Debug, we don't know x = u32 -} - -fn foo2() -> u32 { - let x: impl Debug = 22_u32; - //~^ ERROR: `impl Trait` not allowed outside of function and method return types [E0562] - let y: impl Debug = x; - //~^ ERROR: `impl Trait` not allowed outside of function and method return types [E0562] - same_type((x, y)); // ERROR - x -} - -fn same_type(x: (T, T)) {} - -fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let2.stderr b/src/test/ui/type-alias-impl-trait/type_of_a_let2.stderr deleted file mode 100644 index 7a1825a8e2d9a..0000000000000 --- a/src/test/ui/type-alias-impl-trait/type_of_a_let2.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/type_of_a_let2.rs:9:12 - | -LL | let x: impl Debug = 22_u32; - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/type_of_a_let2.rs:15:12 - | -LL | let x: impl Debug = 22_u32; - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/type_of_a_let2.rs:17:12 - | -LL | let y: impl Debug = x; - | ^^^^^^^^^^ - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0562`. From bb583f72e3ac42997eaa3522eca54b5326483351 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 25 Aug 2021 20:07:12 -0300 Subject: [PATCH 31/32] Add field types tait tests --- .../ui/type-alias-impl-trait/field-types.rs | 20 ++++++++++++++++++ .../type-alias-impl-trait/field-types.stderr | 21 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/test/ui/type-alias-impl-trait/field-types.rs create mode 100644 src/test/ui/type-alias-impl-trait/field-types.stderr diff --git a/src/test/ui/type-alias-impl-trait/field-types.rs b/src/test/ui/type-alias-impl-trait/field-types.rs new file mode 100644 index 0000000000000..91494a82d0fb2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/field-types.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// FIXME This should compile, but it currently doesn't + +use std::fmt::Debug; + +type Foo = impl Debug; +//~^ ERROR: could not find defining uses + +struct Bar { + foo: Foo, +} + +fn bar() -> Bar { + Bar { foo: "foo" } + //~^ ERROR: mismatched types [E0308] +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/field-types.stderr b/src/test/ui/type-alias-impl-trait/field-types.stderr new file mode 100644 index 0000000000000..18c2abbdf3721 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/field-types.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/field-types.rs:16:16 + | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | Bar { foo: "foo" } + | ^^^^^ expected opaque type, found `&str` + | + = note: expected opaque type `impl Debug` + found reference `&'static str` + +error: could not find defining uses + --> $DIR/field-types.rs:8:12 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 4fcae2c89113e0767ee066a42f418261cebdc4bd Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 25 Aug 2021 20:32:31 -0300 Subject: [PATCH 32/32] Add const and static TAIT tests --- .../static-const-types.rs | 16 +++++++++ .../static-const-types.stderr | 33 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/test/ui/type-alias-impl-trait/static-const-types.rs create mode 100644 src/test/ui/type-alias-impl-trait/static-const-types.stderr diff --git a/src/test/ui/type-alias-impl-trait/static-const-types.rs b/src/test/ui/type-alias-impl-trait/static-const-types.rs new file mode 100644 index 0000000000000..f630d27833503 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/static-const-types.rs @@ -0,0 +1,16 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// FIXME: This should compile, but it currently doesn't + +use std::fmt::Debug; + +type Foo = impl Debug; +//~^ ERROR: could not find defining uses + +static FOO1: Foo = 22_u32; +//~^ ERROR: mismatched types [E0308] +const FOO2: Foo = 22_u32; +//~^ ERROR: mismatched types [E0308] + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/static-const-types.stderr b/src/test/ui/type-alias-impl-trait/static-const-types.stderr new file mode 100644 index 0000000000000..72083d014fe3a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/static-const-types.stderr @@ -0,0 +1,33 @@ +error[E0308]: mismatched types + --> $DIR/static-const-types.rs:11:20 + | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | static FOO1: Foo = 22_u32; + | ^^^^^^ expected opaque type, found `u32` + | + = note: expected opaque type `impl Debug` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/static-const-types.rs:13:19 + | +LL | type Foo = impl Debug; + | ---------- the expected opaque type +... +LL | const FOO2: Foo = 22_u32; + | ^^^^^^ expected opaque type, found `u32` + | + = note: expected opaque type `impl Debug` + found type `u32` + +error: could not find defining uses + --> $DIR/static-const-types.rs:8:12 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`.