From b1ad22941b6fc90a177ba896d60b367a8c216a55 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 10 Aug 2023 16:27:49 -0400 Subject: [PATCH 01/11] Allow setting `rla-*` labels via `rustbot` https://github.com/rust-lang/rust-log-analyzer/pull/75 adds a `rla-silenced` label flag that will turn off RLA updates for non-bors tests. Allow setting that labels and others via `rustbot`. --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 6b36e59dfc84d..0b71a67ebd56a 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -18,6 +18,7 @@ allow-unauthenticated = [ "relnotes", "requires-*", "regression-*", + "rla-*", "perf-*", "AsyncAwait-OnDeck", "needs-triage", From 8375fe4710e7f6a0a27770e4c6c5df4317e9bb2f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 26 Nov 2023 18:44:16 -0500 Subject: [PATCH 02/11] Simplify indenting in THIR printing This cuts >100kb from a local librustc_driver.so build, and seems just obviously simpler. --- compiler/rustc_mir_build/src/thir/print.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index c3b2309b7cdae..e449928a64357 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -31,8 +31,8 @@ const INDENT: &str = " "; macro_rules! print_indented { ($writer:ident, $s:expr, $indent_lvl:expr) => { - let indent = (0..$indent_lvl).map(|_| INDENT).collect::>().concat(); - writeln!($writer, "{}{}", indent, $s).expect("unable to write to ThirPrinter"); + $writer.indent($indent_lvl); + writeln!($writer, "{}", $s).expect("unable to write to ThirPrinter"); }; } @@ -48,6 +48,12 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { Self { thir, fmt: String::new() } } + fn indent(&mut self, level: usize) { + for _ in 0..level { + self.fmt.push_str(INDENT); + } + } + fn print(&mut self) { print_indented!(self, "params: [", 0); for param in self.thir.params.iter() { From 16c164fea3b48bd2ddc618377e918565b287b8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 27 Nov 2023 12:29:21 +0100 Subject: [PATCH 03/11] Detect and reject malformed repr(Rust) hints --- compiler/rustc_attr/src/builtin.rs | 6 ++-- ...e-83921-ice.rs => malformed-repr-hints.rs} | 9 +++++ ...ice.stderr => malformed-repr-hints.stderr} | 34 ++++++++++++++----- 3 files changed, 38 insertions(+), 11 deletions(-) rename tests/ui/repr/{issue-83921-ice.rs => malformed-repr-hints.rs} (76%) rename tests/ui/repr/{issue-83921-ice.stderr => malformed-repr-hints.stderr} (58%) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 7e87d1c31301b..609d75733b2c8 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -985,7 +985,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { Ok(literal) => acc.push(ReprPacked(literal)), Err(message) => literal_error = Some(message), }; - } else if matches!(name, sym::C | sym::simd | sym::transparent) + } else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent) || int_type_of_word(name).is_some() { recognised = true; @@ -1018,7 +1018,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { }); } else if matches!( meta_item.name_or_empty(), - sym::C | sym::simd | sym::transparent + sym::Rust | sym::C | sym::simd | sym::transparent ) || int_type_of_word(meta_item.name_or_empty()).is_some() { recognised = true; @@ -1043,7 +1043,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { ); } else if matches!( meta_item.name_or_empty(), - sym::C | sym::simd | sym::transparent + sym::Rust | sym::C | sym::simd | sym::transparent ) || int_type_of_word(meta_item.name_or_empty()).is_some() { recognised = true; diff --git a/tests/ui/repr/issue-83921-ice.rs b/tests/ui/repr/malformed-repr-hints.rs similarity index 76% rename from tests/ui/repr/issue-83921-ice.rs rename to tests/ui/repr/malformed-repr-hints.rs index 70583eb9bd332..27840b5f835d8 100644 --- a/tests/ui/repr/issue-83921-ice.rs +++ b/tests/ui/repr/malformed-repr-hints.rs @@ -19,6 +19,15 @@ struct S3; //~^ ERROR: incorrect `repr(align)` attribute format struct S4; +// Regression test for issue #118334: +#[repr(Rust(u8))] +//~^ ERROR: invalid representation hint +#[repr(Rust(0))] +//~^ ERROR: invalid representation hint +#[repr(Rust = 0)] +//~^ ERROR: invalid representation hint +struct S5; + #[repr(i8())] //~^ ERROR: invalid representation hint enum E1 { A, B } diff --git a/tests/ui/repr/issue-83921-ice.stderr b/tests/ui/repr/malformed-repr-hints.stderr similarity index 58% rename from tests/ui/repr/issue-83921-ice.stderr rename to tests/ui/repr/malformed-repr-hints.stderr index 32c450410eace..6fb927557619f 100644 --- a/tests/ui/repr/issue-83921-ice.stderr +++ b/tests/ui/repr/malformed-repr-hints.stderr @@ -1,46 +1,64 @@ error[E0552]: incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all - --> $DIR/issue-83921-ice.rs:6:8 + --> $DIR/malformed-repr-hints.rs:6:8 | LL | #[repr(packed())] | ^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: `align` needs an argument - --> $DIR/issue-83921-ice.rs:10:8 + --> $DIR/malformed-repr-hints.rs:10:8 | LL | #[repr(align)] | ^^^^^ help: supply an argument here: `align(...)` error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses - --> $DIR/issue-83921-ice.rs:14:8 + --> $DIR/malformed-repr-hints.rs:14:8 | LL | #[repr(align(2, 4))] | ^^^^^^^^^^^ error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses - --> $DIR/issue-83921-ice.rs:18:8 + --> $DIR/malformed-repr-hints.rs:18:8 | LL | #[repr(align())] | ^^^^^^^ +error[E0552]: invalid representation hint: `Rust` does not take a parenthesized argument list + --> $DIR/malformed-repr-hints.rs:23:8 + | +LL | #[repr(Rust(u8))] + | ^^^^^^^^ + +error[E0552]: invalid representation hint: `Rust` does not take a parenthesized argument list + --> $DIR/malformed-repr-hints.rs:25:8 + | +LL | #[repr(Rust(0))] + | ^^^^^^^ + +error[E0552]: invalid representation hint: `Rust` does not take a value + --> $DIR/malformed-repr-hints.rs:27:8 + | +LL | #[repr(Rust = 0)] + | ^^^^^^^^ + error[E0552]: invalid representation hint: `i8` does not take a parenthesized argument list - --> $DIR/issue-83921-ice.rs:22:8 + --> $DIR/malformed-repr-hints.rs:31:8 | LL | #[repr(i8())] | ^^^^ error[E0552]: invalid representation hint: `u32` does not take a parenthesized argument list - --> $DIR/issue-83921-ice.rs:26:8 + --> $DIR/malformed-repr-hints.rs:35:8 | LL | #[repr(u32(42))] | ^^^^^^^ error[E0552]: invalid representation hint: `i64` does not take a value - --> $DIR/issue-83921-ice.rs:30:8 + --> $DIR/malformed-repr-hints.rs:39:8 | LL | #[repr(i64 = 2)] | ^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0552, E0589, E0693. For more information about an error, try `rustc --explain E0552`. From e65c060d78db59c5f21cb13f4ec322e407f0a642 Mon Sep 17 00:00:00 2001 From: Hirochika Matsumoto Date: Wed, 3 May 2023 22:32:52 +0900 Subject: [PATCH 04/11] Detect Python-like slicing and suggest how to fix Fix #108215 --- compiler/rustc_ast/src/token.rs | 5 +++++ compiler/rustc_parse/src/parser/stmt.rs | 16 ++++++++++++++++ .../range-index-instead-of-colon.rs | 8 ++++++++ .../range-index-instead-of-colon.stderr | 18 ++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 tests/ui/suggestions/range-index-instead-of-colon.rs create mode 100644 tests/ui/suggestions/range-index-instead-of-colon.stderr diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 3189fcf7ff9bf..a7c6f8c5d8c26 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -756,6 +756,11 @@ impl Token { ) } + /// Returns `true` if the token is the integer literal. + pub fn is_integer_lit(&self) -> bool { + matches!(self.kind, Literal(Lit { kind: LitKind::Integer, .. })) + } + /// Returns `true` if the token is a non-raw identifier for which `pred` holds. pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool { match self.ident() { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 5316dde609605..94d200188eafb 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -567,6 +567,22 @@ impl<'a> Parser<'a> { snapshot.recover_diff_marker(); } if self.token == token::Colon { + // if a previous and next token of the current one is + // integer literal (e.g. `1:42`), it's likely a range + // expression for Pythonistas and we can suggest so. + if self.prev_token.is_integer_lit() + && self.look_ahead(1, |token| token.is_integer_lit()) + { + // TODO(hkmatsumoto): Might be better to trigger + // this only when parsing an index expression. + err.span_suggestion_verbose( + self.token.span, + "you might have meant to make a slice with range index", + "..", + Applicability::MaybeIncorrect, + ); + } + // if next token is following a colon, it's likely a path // and we can suggest a path separator self.bump(); diff --git a/tests/ui/suggestions/range-index-instead-of-colon.rs b/tests/ui/suggestions/range-index-instead-of-colon.rs new file mode 100644 index 0000000000000..a5e0098544db3 --- /dev/null +++ b/tests/ui/suggestions/range-index-instead-of-colon.rs @@ -0,0 +1,8 @@ +// edition:2021 + +fn main() { + &[1, 2, 3][1:2]; + //~^ ERROR: expected one of + //~| HELP: you might have meant to make a slice with range index + //~| HELP: maybe write a path separator here +} \ No newline at end of file diff --git a/tests/ui/suggestions/range-index-instead-of-colon.stderr b/tests/ui/suggestions/range-index-instead-of-colon.stderr new file mode 100644 index 0000000000000..72e400fba0ac8 --- /dev/null +++ b/tests/ui/suggestions/range-index-instead-of-colon.stderr @@ -0,0 +1,18 @@ +error: expected one of `.`, `?`, `]`, or an operator, found `:` + --> $DIR/range-index-instead-of-colon.rs:4:17 + | +LL | &[1, 2, 3][1:2]; + | ^ expected one of `.`, `?`, `]`, or an operator + | + = note: type ascription syntax has been removed, see issue #101728 +help: you might have meant to make a slice with range index + | +LL | &[1, 2, 3][1..2]; + | ~~ +help: maybe write a path separator here + | +LL | &[1, 2, 3][1::2]; + | ~~ + +error: aborting due to previous error + From 61c3e4d56ecc77899095590d9fd03ffc39e9849e Mon Sep 17 00:00:00 2001 From: Hirochika Matsumoto Date: Wed, 3 May 2023 22:54:22 +0900 Subject: [PATCH 05/11] Make tidy test happy --- compiler/rustc_parse/src/parser/stmt.rs | 2 +- tests/ui/suggestions/range-index-instead-of-colon.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 94d200188eafb..71db5609edc2e 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -573,7 +573,7 @@ impl<'a> Parser<'a> { if self.prev_token.is_integer_lit() && self.look_ahead(1, |token| token.is_integer_lit()) { - // TODO(hkmatsumoto): Might be better to trigger + // FIXME(hkmatsumoto): Might be better to trigger // this only when parsing an index expression. err.span_suggestion_verbose( self.token.span, diff --git a/tests/ui/suggestions/range-index-instead-of-colon.rs b/tests/ui/suggestions/range-index-instead-of-colon.rs index a5e0098544db3..f183590d2c7a2 100644 --- a/tests/ui/suggestions/range-index-instead-of-colon.rs +++ b/tests/ui/suggestions/range-index-instead-of-colon.rs @@ -5,4 +5,4 @@ fn main() { //~^ ERROR: expected one of //~| HELP: you might have meant to make a slice with range index //~| HELP: maybe write a path separator here -} \ No newline at end of file +} From 730d299354f7ef09d8e30609110fc499e0e22d71 Mon Sep 17 00:00:00 2001 From: Hirochika Matsumoto Date: Tue, 16 May 2023 14:53:05 +0900 Subject: [PATCH 06/11] Address review feedbacks Also addressed merge conflicts upon rebasing. --- compiler/rustc_parse/src/parser/stmt.rs | 33 ++++++++++--------- .../range-index-instead-of-colon.rs | 1 - .../range-index-instead-of-colon.stderr | 7 +--- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 71db5609edc2e..391a4777bd944 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -571,6 +571,7 @@ impl<'a> Parser<'a> { // integer literal (e.g. `1:42`), it's likely a range // expression for Pythonistas and we can suggest so. if self.prev_token.is_integer_lit() + && self.may_recover() && self.look_ahead(1, |token| token.is_integer_lit()) { // FIXME(hkmatsumoto): Might be better to trigger @@ -581,22 +582,22 @@ impl<'a> Parser<'a> { "..", Applicability::MaybeIncorrect, ); - } - - // if next token is following a colon, it's likely a path - // and we can suggest a path separator - self.bump(); - if self.token.span.lo() == self.prev_token.span.hi() { - err.span_suggestion_verbose( - self.prev_token.span, - "maybe write a path separator here", - "::", - Applicability::MaybeIncorrect, - ); - } - if self.sess.unstable_features.is_nightly_build() { - // FIXME(Nilstrieb): Remove this again after a few months. - err.note("type ascription syntax has been removed, see issue #101728 "); + } else { + // if next token is following a colon, it's likely a path + // and we can suggest a path separator + self.bump(); + if self.token.span.lo() == self.prev_token.span.hi() { + err.span_suggestion_verbose( + self.prev_token.span, + "maybe write a path separator here", + "::", + Applicability::MaybeIncorrect, + ); + } + if self.sess.unstable_features.is_nightly_build() { + // FIXME(Nilstrieb): Remove this again after a few months. + err.note("type ascription syntax has been removed, see issue #101728 "); + } } } diff --git a/tests/ui/suggestions/range-index-instead-of-colon.rs b/tests/ui/suggestions/range-index-instead-of-colon.rs index f183590d2c7a2..0805102de7844 100644 --- a/tests/ui/suggestions/range-index-instead-of-colon.rs +++ b/tests/ui/suggestions/range-index-instead-of-colon.rs @@ -4,5 +4,4 @@ fn main() { &[1, 2, 3][1:2]; //~^ ERROR: expected one of //~| HELP: you might have meant to make a slice with range index - //~| HELP: maybe write a path separator here } diff --git a/tests/ui/suggestions/range-index-instead-of-colon.stderr b/tests/ui/suggestions/range-index-instead-of-colon.stderr index 72e400fba0ac8..c7a12e9e4fb15 100644 --- a/tests/ui/suggestions/range-index-instead-of-colon.stderr +++ b/tests/ui/suggestions/range-index-instead-of-colon.stderr @@ -4,15 +4,10 @@ error: expected one of `.`, `?`, `]`, or an operator, found `:` LL | &[1, 2, 3][1:2]; | ^ expected one of `.`, `?`, `]`, or an operator | - = note: type ascription syntax has been removed, see issue #101728 help: you might have meant to make a slice with range index | LL | &[1, 2, 3][1..2]; | ~~ -help: maybe write a path separator here - | -LL | &[1, 2, 3][1::2]; - | ~~ -error: aborting due to previous error +error: aborting due to 1 previous error From acec70de9b0b76cb5b077b030360fa217ccdcdec Mon Sep 17 00:00:00 2001 From: Hirochika Matsumoto Date: Mon, 27 Nov 2023 22:18:03 +0900 Subject: [PATCH 07/11] Change help message to make some sense in broader context --- compiler/rustc_parse/src/parser/stmt.rs | 2 +- tests/ui/suggestions/range-index-instead-of-colon.rs | 2 +- tests/ui/suggestions/range-index-instead-of-colon.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 391a4777bd944..620ba4a3cb363 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -578,7 +578,7 @@ impl<'a> Parser<'a> { // this only when parsing an index expression. err.span_suggestion_verbose( self.token.span, - "you might have meant to make a slice with range index", + "you might have meant a range expression", "..", Applicability::MaybeIncorrect, ); diff --git a/tests/ui/suggestions/range-index-instead-of-colon.rs b/tests/ui/suggestions/range-index-instead-of-colon.rs index 0805102de7844..3267527ecf2a7 100644 --- a/tests/ui/suggestions/range-index-instead-of-colon.rs +++ b/tests/ui/suggestions/range-index-instead-of-colon.rs @@ -3,5 +3,5 @@ fn main() { &[1, 2, 3][1:2]; //~^ ERROR: expected one of - //~| HELP: you might have meant to make a slice with range index + //~| HELP: you might have meant a range expression } diff --git a/tests/ui/suggestions/range-index-instead-of-colon.stderr b/tests/ui/suggestions/range-index-instead-of-colon.stderr index c7a12e9e4fb15..df29356cc16b3 100644 --- a/tests/ui/suggestions/range-index-instead-of-colon.stderr +++ b/tests/ui/suggestions/range-index-instead-of-colon.stderr @@ -4,7 +4,7 @@ error: expected one of `.`, `?`, `]`, or an operator, found `:` LL | &[1, 2, 3][1:2]; | ^ expected one of `.`, `?`, `]`, or an operator | -help: you might have meant to make a slice with range index +help: you might have meant a range expression | LL | &[1, 2, 3][1..2]; | ~~ From 9e9ca4aaccdc06f4767c3034c9a09e8ba3cb2300 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Mon, 27 Nov 2023 18:40:00 +0300 Subject: [PATCH 08/11] add stable_mir output test --- src/tools/tidy/src/ui_tests.rs | 2 +- tests/ui/stable-mir-print/basic_function.rs | 14 ++ .../ui/stable-mir-print/basic_function.stdout | 226 ++++++++++++++++++ 3 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 tests/ui/stable-mir-print/basic_function.rs create mode 100644 tests/ui/stable-mir-print/basic_function.stdout diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index dfa386b49de7c..0fb57bf6f6c80 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1852; -const ROOT_ENTRY_LIMIT: usize = 867; +const ROOT_ENTRY_LIMIT: usize = 868; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/ui/stable-mir-print/basic_function.rs b/tests/ui/stable-mir-print/basic_function.rs new file mode 100644 index 0000000000000..8b8a3154830ac --- /dev/null +++ b/tests/ui/stable-mir-print/basic_function.rs @@ -0,0 +1,14 @@ +// compile-flags: -Z unpretty=stable-mir +// check-pass + +fn foo(i:i32) -> i32 { + i + 1 +} + +fn bar(vec: &mut Vec) -> Vec { + let mut new_vec = vec.clone(); + new_vec.push(1); + new_vec +} + +fn main(){} diff --git a/tests/ui/stable-mir-print/basic_function.stdout b/tests/ui/stable-mir-print/basic_function.stdout new file mode 100644 index 0000000000000..e54ebe2b2c03f --- /dev/null +++ b/tests/ui/stable-mir-print/basic_function.stdout @@ -0,0 +1,226 @@ +// WARNING: This is highly experimental output it's intended for stable-mir developers only. +// If you find a bug or want to improve the output open a issue at https://github.com/rust-lang/project-stable-mir. +fn foo(_0: i32) -> i32 { + let mut _0: (i32, bool); +} + bb0: { + _2 = 1 Add const 1_i32 + } + bb1: { + _0 = move _2 + } +fn bar(_0: &mut Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}) -> Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +} { + let mut _0: Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}; + let mut _1: &Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}; + let _2: (); + let mut _3: &mut Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}; +} + bb0: { + _3 = refShared1 + } + bb1: { + _5 = refMut { + kind: TwoPhaseBorrow, +}2 + } + bb2: { + _0 = move _2 + } + bb3: { + } + bb4: { + } +fn main() -> () { +} + bb0: { + } From 8221f9c837f46461d2dd6f29a4468b3a0ee4b508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 2 Nov 2023 21:22:42 +0000 Subject: [PATCH 09/11] Account for `!` arm in tail `match` expr On functions with a default return type that influences the coerced type of `match` arms, check if the failing arm is actually of type `!`. If so, suggest changing the return type so the coercion against the prior arms is successful. ``` error[E0308]: `match` arms have incompatible types --> $DIR/match-tail-expr-never-type-error.rs:9:13 | LL | fn bar(a: bool) { | - help: try adding a return type: `-> i32` LL | / match a { LL | | true => 1, | | - this is found to be of type `{integer}` LL | | false => { LL | | never() | | ^^^^^^^ | | | | | expected integer, found `()` | | this expression is of type `!`, but it get's coerced to `()` due to its surrounding expression LL | | } LL | | } | |_____- `match` arms have incompatible types ``` Fix #24157. --- compiler/rustc_hir_typeck/src/_match.rs | 36 ++++++++++++++++++- compiler/rustc_hir_typeck/src/coercion.rs | 1 + compiler/rustc_hir_typeck/src/expr.rs | 7 ++-- .../src/fn_ctxt/suggestions.rs | 1 - .../match/match-tail-expr-never-type-error.rs | 16 +++++++++ .../match-tail-expr-never-type-error.stderr | 21 +++++++++++ 6 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 tests/ui/match/match-tail-expr-never-type-error.rs create mode 100644 tests/ui/match/match-tail-expr-never-type-error.stderr diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index a29d9c95e5ea0..e7cbbc713353f 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -139,7 +139,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &cause, Some(arm.body), arm_ty, - |err| self.suggest_removing_semicolon_for_coerce(err, expr, arm_ty, prior_arm), + |err| { + self.explain_never_type_coerced_to_unit(err, arm, arm_ty, prior_arm, expr); + }, false, ); @@ -177,6 +179,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { coercion.complete(self) } + fn explain_never_type_coerced_to_unit( + &self, + err: &mut Diagnostic, + arm: &hir::Arm<'tcx>, + arm_ty: Ty<'tcx>, + prior_arm: Option<(Option, Ty<'tcx>, Span)>, + expr: &hir::Expr<'tcx>, + ) { + if let hir::ExprKind::Block(block, _) = arm.body.kind + && let Some(expr) = block.expr + && let arm_tail_ty = self.node_ty(expr.hir_id) + && arm_tail_ty.is_never() + && !arm_ty.is_never() + { + err.span_label( + expr.span, + format!( + "this expression is of type `!`, but it is coerced to `{arm_ty}` due to its \ + surrounding expression", + ), + ); + self.suggest_mismatched_types_on_tail( + err, + expr, + arm_ty, + prior_arm.map_or(arm_tail_ty, |(_, ty, _)| ty), + expr.hir_id, + ); + } + self.suggest_removing_semicolon_for_coerce(err, expr, arm_ty, prior_arm) + } + fn suggest_removing_semicolon_for_coerce( &self, diag: &mut Diagnostic, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index ae2a4a9504ce3..587038d57bdfd 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1715,6 +1715,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // label pointing out the cause for the type coercion will be wrong // as prior return coercions would not be relevant (#57664). let fn_decl = if let (Some(expr), Some(blk_id)) = (expression, blk_id) { + fcx.suggest_missing_semicolon(&mut err, expr, expected, false); let pointing_at_return_type = fcx.suggest_mismatched_types_on_tail(&mut err, expr, expected, found, blk_id); if let (Some(cond_expr), true, false) = ( diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f16269795e985..7f15478349e79 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -663,8 +663,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { coerce.coerce_forced_unit( self, &cause, - |err| { - self.suggest_mismatched_types_on_tail(err, expr, ty, e_ty, target_id); + |mut err| { + self.suggest_missing_semicolon(&mut err, expr, e_ty, false); + self.suggest_mismatched_types_on_tail( + &mut err, expr, ty, e_ty, target_id, + ); let error = Some(Sorts(ExpectedFound { expected: ty, found: e_ty })); self.annotate_loop_expected_due_to_inference(err, expr, error); if let Some(val) = ty_kind_suggestion(ty) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 6660bea03d8b7..c74ef8f271338 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -72,7 +72,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { blk_id: hir::HirId, ) -> bool { let expr = expr.peel_drop_temps(); - self.suggest_missing_semicolon(err, expr, expected, false); let mut pointing_at_return_type = false; if let hir::ExprKind::Break(..) = expr.kind { // `break` type mismatches provide better context for tail `loop` expressions. diff --git a/tests/ui/match/match-tail-expr-never-type-error.rs b/tests/ui/match/match-tail-expr-never-type-error.rs new file mode 100644 index 0000000000000..786ed3fa904be --- /dev/null +++ b/tests/ui/match/match-tail-expr-never-type-error.rs @@ -0,0 +1,16 @@ +fn never() -> ! { + loop {} +} + +fn bar(a: bool) { + match a { + true => 1, + false => { + never() //~ ERROR `match` arms have incompatible types + } + } +} +fn main() { + bar(true); + bar(false); +} diff --git a/tests/ui/match/match-tail-expr-never-type-error.stderr b/tests/ui/match/match-tail-expr-never-type-error.stderr new file mode 100644 index 0000000000000..226d33daeb254 --- /dev/null +++ b/tests/ui/match/match-tail-expr-never-type-error.stderr @@ -0,0 +1,21 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/match-tail-expr-never-type-error.rs:9:13 + | +LL | fn bar(a: bool) { + | - help: try adding a return type: `-> i32` +LL | / match a { +LL | | true => 1, + | | - this is found to be of type `{integer}` +LL | | false => { +LL | | never() + | | ^^^^^^^ + | | | + | | expected integer, found `()` + | | this expression is of type `!`, but it is coerced to `()` due to its surrounding expression +LL | | } +LL | | } + | |_____- `match` arms have incompatible types + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 45fc842ed93d206d3923b869eeb1437cd62e0be8 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 27 Nov 2023 18:55:32 +0100 Subject: [PATCH 10/11] rustc_span: Use correct edit distance start length for suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise the suggestions can be off-base for non-ASCII identifiers. For example suggesting that `Ok` is a name similar to `读文`. --- compiler/rustc_span/src/edit_distance.rs | 6 +++++- tests/ui/suggestions/non_ascii_ident.rs | 4 ++++ tests/ui/suggestions/non_ascii_ident.stderr | 9 +++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/ui/suggestions/non_ascii_ident.rs create mode 100644 tests/ui/suggestions/non_ascii_ident.stderr diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs index 96a118e590f39..14cb1d6d362e2 100644 --- a/compiler/rustc_span/src/edit_distance.rs +++ b/compiler/rustc_span/src/edit_distance.rs @@ -188,7 +188,11 @@ fn find_best_match_for_name_impl( return Some(*c); } - let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3); + // `fn edit_distance()` use `chars()` to calculate edit distance, so we must + // also use `chars()` (and not `str::len()`) to calculate length here. + let lookup_len = lookup.chars().count(); + + let mut dist = dist.unwrap_or_else(|| cmp::max(lookup_len, 3) / 3); let mut best = None; // store the candidates with the same distance, only for `use_substring_score` current. let mut next_candidates = vec![]; diff --git a/tests/ui/suggestions/non_ascii_ident.rs b/tests/ui/suggestions/non_ascii_ident.rs new file mode 100644 index 0000000000000..679ac4bcb6e3f --- /dev/null +++ b/tests/ui/suggestions/non_ascii_ident.rs @@ -0,0 +1,4 @@ +fn main() { + // There shall be no suggestions here. In particular not `Ok`. + let _ = 读文; //~ ERROR cannot find value `读文` in this scope +} diff --git a/tests/ui/suggestions/non_ascii_ident.stderr b/tests/ui/suggestions/non_ascii_ident.stderr new file mode 100644 index 0000000000000..79fca3e1f612c --- /dev/null +++ b/tests/ui/suggestions/non_ascii_ident.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `读文` in this scope + --> $DIR/non_ascii_ident.rs:3:13 + | +LL | let _ = 读文; + | ^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. From 765a713dff0c4778b4f13f88d597fc351f903030 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Sat, 25 Nov 2023 15:45:44 -0500 Subject: [PATCH 11/11] Address unused tuple struct fields in rustdoc --- src/librustdoc/clean/mod.rs | 7 ++----- src/librustdoc/clean/types.rs | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dc9098d3ade7b..fe1f43835ef3a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1821,11 +1821,8 @@ fn maybe_expand_private_type_alias<'tcx>( } _ => None, }); - if let Some(ct) = const_ { - args.insert( - param.def_id.to_def_id(), - SubstParam::Constant(clean_const(ct, cx)), - ); + if let Some(_) = const_ { + args.insert(param.def_id.to_def_id(), SubstParam::Constant); } // FIXME(const_generics_defaults) indices.consts += 1; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index f079d01bd8422..7a5cf8031375d 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2546,7 +2546,7 @@ pub(crate) enum TypeBindingKind { pub(crate) enum SubstParam { Type(Type), Lifetime(Lifetime), - Constant(Constant), + Constant, } impl SubstParam {