From e813132e4f8b0c469c9959c2efa1b0629067b3b8 Mon Sep 17 00:00:00 2001 From: SpanishPear Date: Mon, 24 Oct 2022 00:52:59 +1100 Subject: [PATCH 01/21] --wip-- [skip ci] --wip-- [skip ci] get the generic text and put it int he suggestion, but suggestion not working on derive subdiagnostic refactor away from derives and use span_suggestion() instead. Show's the correct(?) generic contents, but overwrites the fn name :( x fmt drop commented code and s/todo/fixme get the correct diagnostic for functions, at least x fmt remove some debugs remove format remove debugs remove useless change remove useless change remove legacy approach correct lookahead + error message contains the ident name fmt refactor code tests add tests remoev debug remove comment --- .../rustc_parse/src/parser/diagnostics.rs | 57 ++++++++++++++++++- .../suggest_misplaced_generics/enum.fixed | 10 ++++ .../parser/suggest_misplaced_generics/enum.rs | 10 ++++ .../suggest_misplaced_generics/enum.stderr | 13 +++++ .../existing_generics.rs | 9 +++ .../existing_generics.stderr | 10 ++++ .../fn-complex-generics.fixed | 10 ++++ .../fn-complex-generics.rs | 10 ++++ .../fn-complex-generics.stderr | 13 +++++ .../fn-invalid-generics.rs | 8 +++ .../fn-invalid-generics.stderr | 8 +++ .../fn-simple.fixed | 10 ++++ .../suggest_misplaced_generics/fn-simple.rs | 10 ++++ .../fn-simple.stderr | 13 +++++ .../suggest_misplaced_generics/struct.fixed | 10 ++++ .../suggest_misplaced_generics/struct.rs | 10 ++++ .../suggest_misplaced_generics/struct.stderr | 13 +++++ .../suggest_misplaced_generics/trait.fixed | 12 ++++ .../suggest_misplaced_generics/trait.rs | 12 ++++ .../suggest_misplaced_generics/trait.stderr | 13 +++++ .../suggest_misplaced_generics/type.fixed | 10 ++++ .../parser/suggest_misplaced_generics/type.rs | 10 ++++ .../suggest_misplaced_generics/type.stderr | 13 +++++ 23 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/parser/suggest_misplaced_generics/enum.fixed create mode 100644 src/test/ui/parser/suggest_misplaced_generics/enum.rs create mode 100644 src/test/ui/parser/suggest_misplaced_generics/enum.stderr create mode 100644 src/test/ui/parser/suggest_misplaced_generics/existing_generics.rs create mode 100644 src/test/ui/parser/suggest_misplaced_generics/existing_generics.stderr create mode 100644 src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed create mode 100644 src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs create mode 100644 src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr create mode 100644 src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs create mode 100644 src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.stderr create mode 100644 src/test/ui/parser/suggest_misplaced_generics/fn-simple.fixed create mode 100644 src/test/ui/parser/suggest_misplaced_generics/fn-simple.rs create mode 100644 src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr create mode 100644 src/test/ui/parser/suggest_misplaced_generics/struct.fixed create mode 100644 src/test/ui/parser/suggest_misplaced_generics/struct.rs create mode 100644 src/test/ui/parser/suggest_misplaced_generics/struct.stderr create mode 100644 src/test/ui/parser/suggest_misplaced_generics/trait.fixed create mode 100644 src/test/ui/parser/suggest_misplaced_generics/trait.rs create mode 100644 src/test/ui/parser/suggest_misplaced_generics/trait.stderr create mode 100644 src/test/ui/parser/suggest_misplaced_generics/type.fixed create mode 100644 src/test/ui/parser/suggest_misplaced_generics/type.rs create mode 100644 src/test/ui/parser/suggest_misplaced_generics/type.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 4c918c6702ed9..6df9cfd3ff4e3 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -284,7 +284,7 @@ impl<'a> Parser<'a> { self.sess.source_map().span_to_snippet(span) } - pub(super) fn expected_ident_found(&self) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + pub(super) fn expected_ident_found(&mut self) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let valid_follow = &[ TokenKind::Eq, TokenKind::Colon, @@ -324,7 +324,60 @@ impl<'a> Parser<'a> { suggest_raw, suggest_remove_comma, }; - err.into_diagnostic(&self.sess.span_diagnostic) + let mut err = err.into_diagnostic(&self.sess.span_diagnostic); + + // if the token we have is a `<` + // it *might* be a misplaced generic + if self.token == token::Lt { + // all keywords that could have generic applied + let valid_prev_keywords = + [kw::Fn, kw::Type, kw::Struct, kw::Enum, kw::Union, kw::Trait]; + + // If we've expected an identifier, + // and the current token is a '<' + // if the previous token is a valid keyword + // that might use a generic, then suggest a correct + // generic placement (later on) + let maybe_keyword = self.prev_token.clone(); + if valid_prev_keywords.into_iter().any(|x| maybe_keyword.is_keyword(x)) { + // if we have a valid keyword, attempt to parse generics + // also obtain the keywords symbol + match self.parse_generics() { + Ok(generic) => { + if let TokenKind::Ident(symbol, _) = maybe_keyword.kind { + let ident_name = symbol.to_string(); + // at this point, we've found something like + // `fn id` + // and current token should be Ident with the item name (i.e. the function name) + // if there is a `<` after the fn name, then don't show a suggestion, show help + + if !self.look_ahead(1, |t| *t == token::Lt) && + let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) && + let Ok(ident) = self.sess.source_map().span_to_snippet(self.token.span) { + err.span_suggestion_verbose( + generic.span.to(self.token.span), + format!("place the generic parameter name after the {ident_name} name"), + format!(" {ident}{snippet}"), + Applicability::MachineApplicable, + ); + } else { + err.help(format!( + "place the generic parameter name after the {ident_name} name" + )); + } + } + } + Err(err) => { + // if there's an error parsing the generics, + // then don't do a misplaced generics suggestion + // and emit the expected ident error instead; + err.cancel(); + } + } + } + } + + err } pub(super) fn expected_one_of_not_found( diff --git a/src/test/ui/parser/suggest_misplaced_generics/enum.fixed b/src/test/ui/parser/suggest_misplaced_generics/enum.fixed new file mode 100644 index 0000000000000..a9d3e9f86d09c --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/enum.fixed @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +enum Foo { Variant(T) } +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the enum name +//~| SUGGESTION Foo + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/enum.rs b/src/test/ui/parser/suggest_misplaced_generics/enum.rs new file mode 100644 index 0000000000000..2d216ba53cc72 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/enum.rs @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +enum Foo { Variant(T) } +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the enum name +//~| SUGGESTION Foo + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/enum.stderr b/src/test/ui/parser/suggest_misplaced_generics/enum.stderr new file mode 100644 index 0000000000000..521cee4f72898 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/enum.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found `<` + --> $DIR/enum.rs:5:5 + | +LL | enum Foo { Variant(T) } + | ^ expected identifier + | +help: place the generic parameter name after the enum name + | +LL | enum Foo { Variant(T) } + | ~~~~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/suggest_misplaced_generics/existing_generics.rs b/src/test/ui/parser/suggest_misplaced_generics/existing_generics.rs new file mode 100644 index 0000000000000..1dc182398d80a --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/existing_generics.rs @@ -0,0 +1,9 @@ +// Issue: 103366 +// there is already an existing generic on f, so don't show a suggestion + +#[allow(unused)] +fn<'a, B: 'a + std::ops::Add> f(_x: B) { } +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the fn name + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/existing_generics.stderr b/src/test/ui/parser/suggest_misplaced_generics/existing_generics.stderr new file mode 100644 index 0000000000000..89716e6f1ed0a --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/existing_generics.stderr @@ -0,0 +1,10 @@ +error: expected identifier, found `<` + --> $DIR/existing_generics.rs:5:3 + | +LL | fn<'a, B: 'a + std::ops::Add> f(_x: B) { } + | ^ expected identifier + | + = help: place the generic parameter name after the fn name + +error: aborting due to previous error + diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed new file mode 100644 index 0000000000000..06947e098ee6a --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +fn f<'a, B: 'a + std::ops::Add>(_x: B) { } +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the fn name +//~| SUGGESTION f<'a, B: 'a + std::ops::Add> + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs new file mode 100644 index 0000000000000..cefce8d08806d --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +fn<'a, B: 'a + std::ops::Add> f(_x: B) { } +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the fn name +//~| SUGGESTION f<'a, B: 'a + std::ops::Add> + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr new file mode 100644 index 0000000000000..7d1b44c44944c --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found `<` + --> $DIR/fn-complex-generics.rs:5:3 + | +LL | fn<'a, B: 'a + std::ops::Add> f(_x: B) { } + | ^ expected identifier + | +help: place the generic parameter name after the fn name + | +LL | fn f<'a, B: 'a + std::ops::Add>(_x: B) { } + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs b/src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs new file mode 100644 index 0000000000000..7fcb6a82ce451 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs @@ -0,0 +1,8 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// The generics fail to parse here, so don't make any suggestions/help + +#[allow(unused)] +fn<~>()> id(x: T) -> T { x } +//~^ ERROR expected identifier, found `<` + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.stderr b/src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.stderr new file mode 100644 index 0000000000000..47e12016938d8 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `<` + --> $DIR/fn-invalid-generics.rs:5:3 + | +LL | fn<~>()> id(x: T) -> T { x } + | ^ expected identifier + +error: aborting due to previous error + diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.fixed b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.fixed new file mode 100644 index 0000000000000..31c5429b16b05 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.fixed @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +fn id(x: T) -> T { x } +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the fn name +//~| SUGGESTION id + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.rs b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.rs new file mode 100644 index 0000000000000..0a466184e996f --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.rs @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +fn id(x: T) -> T { x } +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the fn name +//~| SUGGESTION id + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr new file mode 100644 index 0000000000000..40c4581e513ad --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found `<` + --> $DIR/fn-simple.rs:5:3 + | +LL | fn id(x: T) -> T { x } + | ^ expected identifier + | +help: place the generic parameter name after the fn name + | +LL | fn id(x: T) -> T { x } + | ~~~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/suggest_misplaced_generics/struct.fixed b/src/test/ui/parser/suggest_misplaced_generics/struct.fixed new file mode 100644 index 0000000000000..8627699a83084 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/struct.fixed @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +struct Foo { x: T } +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the struct name +//~| SUGGESTION Foo + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/struct.rs b/src/test/ui/parser/suggest_misplaced_generics/struct.rs new file mode 100644 index 0000000000000..15646b06cfc62 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/struct.rs @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +struct Foo { x: T } +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the struct name +//~| SUGGESTION Foo + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/struct.stderr b/src/test/ui/parser/suggest_misplaced_generics/struct.stderr new file mode 100644 index 0000000000000..ab17ee57e0bcd --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/struct.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found `<` + --> $DIR/struct.rs:5:7 + | +LL | struct Foo { x: T } + | ^ expected identifier + | +help: place the generic parameter name after the struct name + | +LL | struct Foo { x: T } + | ~~~~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/suggest_misplaced_generics/trait.fixed b/src/test/ui/parser/suggest_misplaced_generics/trait.fixed new file mode 100644 index 0000000000000..31ebf1f088fc7 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/trait.fixed @@ -0,0 +1,12 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +trait Foo { + //~^ ERROR expected identifier, found `<` + //~| HELP place the generic parameter name after the trait name + //~| SUGGESTION Foo +} + + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/trait.rs b/src/test/ui/parser/suggest_misplaced_generics/trait.rs new file mode 100644 index 0000000000000..81b6abbd66163 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/trait.rs @@ -0,0 +1,12 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +trait Foo { + //~^ ERROR expected identifier, found `<` + //~| HELP place the generic parameter name after the trait name + //~| SUGGESTION Foo +} + + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/trait.stderr b/src/test/ui/parser/suggest_misplaced_generics/trait.stderr new file mode 100644 index 0000000000000..069683bda1be3 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/trait.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found `<` + --> $DIR/trait.rs:5:6 + | +LL | trait Foo { + | ^ expected identifier + | +help: place the generic parameter name after the trait name + | +LL | trait Foo { + | ~~~~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/suggest_misplaced_generics/type.fixed b/src/test/ui/parser/suggest_misplaced_generics/type.fixed new file mode 100644 index 0000000000000..b04003b803d1c --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/type.fixed @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +type Foo = T; +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the type name +//~| SUGGESTION Foo + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/type.rs b/src/test/ui/parser/suggest_misplaced_generics/type.rs new file mode 100644 index 0000000000000..2d759a8b1ab61 --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/type.rs @@ -0,0 +1,10 @@ +// Issue: 103366 , Suggest fix for misplaced generic params +// run-rustfix + +#[allow(unused)] +type Foo = T; +//~^ ERROR expected identifier, found `<` +//~| HELP place the generic parameter name after the type name +//~| SUGGESTION Foo + +fn main() {} diff --git a/src/test/ui/parser/suggest_misplaced_generics/type.stderr b/src/test/ui/parser/suggest_misplaced_generics/type.stderr new file mode 100644 index 0000000000000..a2832965c6d0e --- /dev/null +++ b/src/test/ui/parser/suggest_misplaced_generics/type.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found `<` + --> $DIR/type.rs:5:5 + | +LL | type Foo = T; + | ^ expected identifier + | +help: place the generic parameter name after the type name + | +LL | type Foo = T; + | ~~~~~~ + +error: aborting due to previous error + From 5287004aa4f9b0685197cc0c009237812fed7047 Mon Sep 17 00:00:00 2001 From: Shrey Sudhir Date: Fri, 2 Dec 2022 00:40:33 +1100 Subject: [PATCH 02/21] Apply automatic suggestions from code review Co-authored-by: Takayuki Maeda --- compiler/rustc_parse/src/parser/diagnostics.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 6df9cfd3ff4e3..1e1e804c0d30a 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -345,7 +345,7 @@ impl<'a> Parser<'a> { match self.parse_generics() { Ok(generic) => { if let TokenKind::Ident(symbol, _) = maybe_keyword.kind { - let ident_name = symbol.to_string(); + let ident_name = symbol; // at this point, we've found something like // `fn id` // and current token should be Ident with the item name (i.e. the function name) @@ -355,9 +355,9 @@ impl<'a> Parser<'a> { let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) && let Ok(ident) = self.sess.source_map().span_to_snippet(self.token.span) { err.span_suggestion_verbose( - generic.span.to(self.token.span), + self.token.span.shrink_to_hi(), format!("place the generic parameter name after the {ident_name} name"), - format!(" {ident}{snippet}"), + snippet, Applicability::MachineApplicable, ); } else { From 655beb4ece8a116c664ae63f26811ba75aa9e0e7 Mon Sep 17 00:00:00 2001 From: Shrey Sudhir Date: Thu, 1 Dec 2022 14:12:33 +0000 Subject: [PATCH 03/21] Attempt to address review comments via github web... --- compiler/rustc_parse/src/parser/diagnostics.rs | 5 ++--- src/test/ui/parser/suggest_misplaced_generics/enum.stderr | 2 +- .../suggest_misplaced_generics/fn-complex-generics.stderr | 2 +- .../ui/parser/suggest_misplaced_generics/fn-simple.stderr | 2 +- src/test/ui/parser/suggest_misplaced_generics/struct.stderr | 2 +- src/test/ui/parser/suggest_misplaced_generics/trait.stderr | 2 +- src/test/ui/parser/suggest_misplaced_generics/type.stderr | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 1e1e804c0d30a..94bedc07ba155 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -352,13 +352,12 @@ impl<'a> Parser<'a> { // if there is a `<` after the fn name, then don't show a suggestion, show help if !self.look_ahead(1, |t| *t == token::Lt) && - let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) && - let Ok(ident) = self.sess.source_map().span_to_snippet(self.token.span) { + let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) { err.span_suggestion_verbose( self.token.span.shrink_to_hi(), format!("place the generic parameter name after the {ident_name} name"), snippet, - Applicability::MachineApplicable, + Applicability::MaybeIncorrect, ); } else { err.help(format!( diff --git a/src/test/ui/parser/suggest_misplaced_generics/enum.stderr b/src/test/ui/parser/suggest_misplaced_generics/enum.stderr index 521cee4f72898..8af94856a4a48 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/enum.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/enum.stderr @@ -7,7 +7,7 @@ LL | enum Foo { Variant(T) } help: place the generic parameter name after the enum name | LL | enum Foo { Variant(T) } - | ~~~~~~ + | ~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr index 7d1b44c44944c..196769cb2b569 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr @@ -7,7 +7,7 @@ LL | fn<'a, B: 'a + std::ops::Add> f(_x: B) { } help: place the generic parameter name after the fn name | LL | fn f<'a, B: 'a + std::ops::Add>(_x: B) { } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr index 40c4581e513ad..0d09d8967b849 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr @@ -7,7 +7,7 @@ LL | fn id(x: T) -> T { x } help: place the generic parameter name after the fn name | LL | fn id(x: T) -> T { x } - | ~~~~~ + | ~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/struct.stderr b/src/test/ui/parser/suggest_misplaced_generics/struct.stderr index ab17ee57e0bcd..32ffdb5e9c308 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/struct.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/struct.stderr @@ -7,7 +7,7 @@ LL | struct Foo { x: T } help: place the generic parameter name after the struct name | LL | struct Foo { x: T } - | ~~~~~~ + | ~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/trait.stderr b/src/test/ui/parser/suggest_misplaced_generics/trait.stderr index 069683bda1be3..01a31b7a85a9d 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/trait.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/trait.stderr @@ -7,7 +7,7 @@ LL | trait Foo { help: place the generic parameter name after the trait name | LL | trait Foo { - | ~~~~~~ + | ~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/type.stderr b/src/test/ui/parser/suggest_misplaced_generics/type.stderr index a2832965c6d0e..1ae73fae7f926 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/type.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/type.stderr @@ -7,7 +7,7 @@ LL | type Foo = T; help: place the generic parameter name after the type name | LL | type Foo = T; - | ~~~~~~ + | ~~~ error: aborting due to previous error From 4447949e400822a02cc9945fc39f06842e6b9439 Mon Sep 17 00:00:00 2001 From: SpanishPear Date: Sun, 22 Jan 2023 16:45:56 +1100 Subject: [PATCH 04/21] revert to previous span --- compiler/rustc_parse/src/parser/diagnostics.rs | 7 ++++--- src/test/ui/parser/suggest_misplaced_generics/enum.stderr | 2 +- .../suggest_misplaced_generics/fn-complex-generics.stderr | 2 +- .../ui/parser/suggest_misplaced_generics/fn-simple.stderr | 2 +- .../ui/parser/suggest_misplaced_generics/struct.stderr | 2 +- src/test/ui/parser/suggest_misplaced_generics/trait.stderr | 2 +- src/test/ui/parser/suggest_misplaced_generics/type.stderr | 2 +- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 94bedc07ba155..9ac3bb946dc42 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -352,11 +352,12 @@ impl<'a> Parser<'a> { // if there is a `<` after the fn name, then don't show a suggestion, show help if !self.look_ahead(1, |t| *t == token::Lt) && - let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) { + let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) && + let Ok(ident) = self.sess.source_map().span_to_snippet(self.token.span) { err.span_suggestion_verbose( - self.token.span.shrink_to_hi(), + generic.span.to(self.token.span), format!("place the generic parameter name after the {ident_name} name"), - snippet, + format!(" {ident}{snippet}"), Applicability::MaybeIncorrect, ); } else { diff --git a/src/test/ui/parser/suggest_misplaced_generics/enum.stderr b/src/test/ui/parser/suggest_misplaced_generics/enum.stderr index 8af94856a4a48..521cee4f72898 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/enum.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/enum.stderr @@ -7,7 +7,7 @@ LL | enum Foo { Variant(T) } help: place the generic parameter name after the enum name | LL | enum Foo { Variant(T) } - | ~~~ + | ~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr index 196769cb2b569..7d1b44c44944c 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr @@ -7,7 +7,7 @@ LL | fn<'a, B: 'a + std::ops::Add> f(_x: B) { } help: place the generic parameter name after the fn name | LL | fn f<'a, B: 'a + std::ops::Add>(_x: B) { } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr index 0d09d8967b849..40c4581e513ad 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr @@ -7,7 +7,7 @@ LL | fn id(x: T) -> T { x } help: place the generic parameter name after the fn name | LL | fn id(x: T) -> T { x } - | ~~~ + | ~~~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/struct.stderr b/src/test/ui/parser/suggest_misplaced_generics/struct.stderr index 32ffdb5e9c308..ab17ee57e0bcd 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/struct.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/struct.stderr @@ -7,7 +7,7 @@ LL | struct Foo { x: T } help: place the generic parameter name after the struct name | LL | struct Foo { x: T } - | ~~~ + | ~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/trait.stderr b/src/test/ui/parser/suggest_misplaced_generics/trait.stderr index 01a31b7a85a9d..069683bda1be3 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/trait.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/trait.stderr @@ -7,7 +7,7 @@ LL | trait Foo { help: place the generic parameter name after the trait name | LL | trait Foo { - | ~~~ + | ~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/parser/suggest_misplaced_generics/type.stderr b/src/test/ui/parser/suggest_misplaced_generics/type.stderr index 1ae73fae7f926..a2832965c6d0e 100644 --- a/src/test/ui/parser/suggest_misplaced_generics/type.stderr +++ b/src/test/ui/parser/suggest_misplaced_generics/type.stderr @@ -7,7 +7,7 @@ LL | type Foo = T; help: place the generic parameter name after the type name | LL | type Foo = T; - | ~~~ + | ~~~~~~ error: aborting due to previous error From 8292d07cc4c9a070a9de808620bb79bab6935f70 Mon Sep 17 00:00:00 2001 From: SpanishPear Date: Sun, 22 Jan 2023 17:16:39 +1100 Subject: [PATCH 05/21] move tests to new rust-lang location --- .../ui/parser/suggest_misplaced_generics/enum.fixed | 0 {src/test => tests}/ui/parser/suggest_misplaced_generics/enum.rs | 0 .../ui/parser/suggest_misplaced_generics/enum.stderr | 0 .../ui/parser/suggest_misplaced_generics/existing_generics.rs | 0 .../ui/parser/suggest_misplaced_generics/existing_generics.stderr | 0 .../parser/suggest_misplaced_generics/fn-complex-generics.fixed | 0 .../ui/parser/suggest_misplaced_generics/fn-complex-generics.rs | 0 .../parser/suggest_misplaced_generics/fn-complex-generics.stderr | 0 .../ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs | 0 .../parser/suggest_misplaced_generics/fn-invalid-generics.stderr | 0 .../ui/parser/suggest_misplaced_generics/fn-simple.fixed | 0 .../ui/parser/suggest_misplaced_generics/fn-simple.rs | 0 .../ui/parser/suggest_misplaced_generics/fn-simple.stderr | 0 .../ui/parser/suggest_misplaced_generics/struct.fixed | 0 .../test => tests}/ui/parser/suggest_misplaced_generics/struct.rs | 0 .../ui/parser/suggest_misplaced_generics/struct.stderr | 0 .../ui/parser/suggest_misplaced_generics/trait.fixed | 0 {src/test => tests}/ui/parser/suggest_misplaced_generics/trait.rs | 0 .../ui/parser/suggest_misplaced_generics/trait.stderr | 0 .../ui/parser/suggest_misplaced_generics/type.fixed | 0 {src/test => tests}/ui/parser/suggest_misplaced_generics/type.rs | 0 .../ui/parser/suggest_misplaced_generics/type.stderr | 0 22 files changed, 0 insertions(+), 0 deletions(-) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/enum.fixed (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/enum.rs (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/enum.stderr (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/existing_generics.rs (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/existing_generics.stderr (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/fn-invalid-generics.stderr (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/fn-simple.fixed (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/fn-simple.rs (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/fn-simple.stderr (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/struct.fixed (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/struct.rs (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/struct.stderr (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/trait.fixed (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/trait.rs (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/trait.stderr (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/type.fixed (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/type.rs (100%) rename {src/test => tests}/ui/parser/suggest_misplaced_generics/type.stderr (100%) diff --git a/src/test/ui/parser/suggest_misplaced_generics/enum.fixed b/tests/ui/parser/suggest_misplaced_generics/enum.fixed similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/enum.fixed rename to tests/ui/parser/suggest_misplaced_generics/enum.fixed diff --git a/src/test/ui/parser/suggest_misplaced_generics/enum.rs b/tests/ui/parser/suggest_misplaced_generics/enum.rs similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/enum.rs rename to tests/ui/parser/suggest_misplaced_generics/enum.rs diff --git a/src/test/ui/parser/suggest_misplaced_generics/enum.stderr b/tests/ui/parser/suggest_misplaced_generics/enum.stderr similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/enum.stderr rename to tests/ui/parser/suggest_misplaced_generics/enum.stderr diff --git a/src/test/ui/parser/suggest_misplaced_generics/existing_generics.rs b/tests/ui/parser/suggest_misplaced_generics/existing_generics.rs similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/existing_generics.rs rename to tests/ui/parser/suggest_misplaced_generics/existing_generics.rs diff --git a/src/test/ui/parser/suggest_misplaced_generics/existing_generics.stderr b/tests/ui/parser/suggest_misplaced_generics/existing_generics.stderr similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/existing_generics.stderr rename to tests/ui/parser/suggest_misplaced_generics/existing_generics.stderr diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed b/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed rename to tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs b/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs rename to tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr b/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr rename to tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs b/tests/ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs rename to tests/ui/parser/suggest_misplaced_generics/fn-invalid-generics.rs diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.stderr b/tests/ui/parser/suggest_misplaced_generics/fn-invalid-generics.stderr similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/fn-invalid-generics.stderr rename to tests/ui/parser/suggest_misplaced_generics/fn-invalid-generics.stderr diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.fixed b/tests/ui/parser/suggest_misplaced_generics/fn-simple.fixed similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/fn-simple.fixed rename to tests/ui/parser/suggest_misplaced_generics/fn-simple.fixed diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.rs b/tests/ui/parser/suggest_misplaced_generics/fn-simple.rs similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/fn-simple.rs rename to tests/ui/parser/suggest_misplaced_generics/fn-simple.rs diff --git a/src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr b/tests/ui/parser/suggest_misplaced_generics/fn-simple.stderr similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/fn-simple.stderr rename to tests/ui/parser/suggest_misplaced_generics/fn-simple.stderr diff --git a/src/test/ui/parser/suggest_misplaced_generics/struct.fixed b/tests/ui/parser/suggest_misplaced_generics/struct.fixed similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/struct.fixed rename to tests/ui/parser/suggest_misplaced_generics/struct.fixed diff --git a/src/test/ui/parser/suggest_misplaced_generics/struct.rs b/tests/ui/parser/suggest_misplaced_generics/struct.rs similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/struct.rs rename to tests/ui/parser/suggest_misplaced_generics/struct.rs diff --git a/src/test/ui/parser/suggest_misplaced_generics/struct.stderr b/tests/ui/parser/suggest_misplaced_generics/struct.stderr similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/struct.stderr rename to tests/ui/parser/suggest_misplaced_generics/struct.stderr diff --git a/src/test/ui/parser/suggest_misplaced_generics/trait.fixed b/tests/ui/parser/suggest_misplaced_generics/trait.fixed similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/trait.fixed rename to tests/ui/parser/suggest_misplaced_generics/trait.fixed diff --git a/src/test/ui/parser/suggest_misplaced_generics/trait.rs b/tests/ui/parser/suggest_misplaced_generics/trait.rs similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/trait.rs rename to tests/ui/parser/suggest_misplaced_generics/trait.rs diff --git a/src/test/ui/parser/suggest_misplaced_generics/trait.stderr b/tests/ui/parser/suggest_misplaced_generics/trait.stderr similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/trait.stderr rename to tests/ui/parser/suggest_misplaced_generics/trait.stderr diff --git a/src/test/ui/parser/suggest_misplaced_generics/type.fixed b/tests/ui/parser/suggest_misplaced_generics/type.fixed similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/type.fixed rename to tests/ui/parser/suggest_misplaced_generics/type.fixed diff --git a/src/test/ui/parser/suggest_misplaced_generics/type.rs b/tests/ui/parser/suggest_misplaced_generics/type.rs similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/type.rs rename to tests/ui/parser/suggest_misplaced_generics/type.rs diff --git a/src/test/ui/parser/suggest_misplaced_generics/type.stderr b/tests/ui/parser/suggest_misplaced_generics/type.stderr similarity index 100% rename from src/test/ui/parser/suggest_misplaced_generics/type.stderr rename to tests/ui/parser/suggest_misplaced_generics/type.stderr From 70bfcc2518dc431cf20cd7d088b954fa348f17d9 Mon Sep 17 00:00:00 2001 From: SpanishPear Date: Tue, 31 Jan 2023 21:44:11 +1100 Subject: [PATCH 06/21] move to multipart spans --- compiler/rustc_parse/src/parser/diagnostics.rs | 11 ++++++----- .../ui/parser/suggest_misplaced_generics/enum.stderr | 5 +++-- .../fn-complex-generics.stderr | 5 +++-- .../suggest_misplaced_generics/fn-simple.stderr | 5 +++-- .../parser/suggest_misplaced_generics/struct.stderr | 5 +++-- .../ui/parser/suggest_misplaced_generics/trait.stderr | 5 +++-- .../ui/parser/suggest_misplaced_generics/type.stderr | 5 +++-- 7 files changed, 24 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 9ac3bb946dc42..1740f2c2c8455 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -352,12 +352,13 @@ impl<'a> Parser<'a> { // if there is a `<` after the fn name, then don't show a suggestion, show help if !self.look_ahead(1, |t| *t == token::Lt) && - let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) && - let Ok(ident) = self.sess.source_map().span_to_snippet(self.token.span) { - err.span_suggestion_verbose( - generic.span.to(self.token.span), + let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) { + err.multipart_suggestion_verbose( format!("place the generic parameter name after the {ident_name} name"), - format!(" {ident}{snippet}"), + vec![ + (self.token.span.shrink_to_hi(), snippet), + (generic.span, String::new()) + ], Applicability::MaybeIncorrect, ); } else { diff --git a/tests/ui/parser/suggest_misplaced_generics/enum.stderr b/tests/ui/parser/suggest_misplaced_generics/enum.stderr index 521cee4f72898..5f5947627ee5c 100644 --- a/tests/ui/parser/suggest_misplaced_generics/enum.stderr +++ b/tests/ui/parser/suggest_misplaced_generics/enum.stderr @@ -6,8 +6,9 @@ LL | enum Foo { Variant(T) } | help: place the generic parameter name after the enum name | -LL | enum Foo { Variant(T) } - | ~~~~~~ +LL - enum Foo { Variant(T) } +LL + enum Foo { Variant(T) } + | error: aborting due to previous error diff --git a/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr b/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr index 7d1b44c44944c..061d0910a742d 100644 --- a/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr +++ b/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.stderr @@ -6,8 +6,9 @@ LL | fn<'a, B: 'a + std::ops::Add> f(_x: B) { } | help: place the generic parameter name after the fn name | -LL | fn f<'a, B: 'a + std::ops::Add>(_x: B) { } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - fn<'a, B: 'a + std::ops::Add> f(_x: B) { } +LL + fn f<'a, B: 'a + std::ops::Add>(_x: B) { } + | error: aborting due to previous error diff --git a/tests/ui/parser/suggest_misplaced_generics/fn-simple.stderr b/tests/ui/parser/suggest_misplaced_generics/fn-simple.stderr index 40c4581e513ad..e749f1a0d00d6 100644 --- a/tests/ui/parser/suggest_misplaced_generics/fn-simple.stderr +++ b/tests/ui/parser/suggest_misplaced_generics/fn-simple.stderr @@ -6,8 +6,9 @@ LL | fn id(x: T) -> T { x } | help: place the generic parameter name after the fn name | -LL | fn id(x: T) -> T { x } - | ~~~~~ +LL - fn id(x: T) -> T { x } +LL + fn id(x: T) -> T { x } + | error: aborting due to previous error diff --git a/tests/ui/parser/suggest_misplaced_generics/struct.stderr b/tests/ui/parser/suggest_misplaced_generics/struct.stderr index ab17ee57e0bcd..2b650907092d1 100644 --- a/tests/ui/parser/suggest_misplaced_generics/struct.stderr +++ b/tests/ui/parser/suggest_misplaced_generics/struct.stderr @@ -6,8 +6,9 @@ LL | struct Foo { x: T } | help: place the generic parameter name after the struct name | -LL | struct Foo { x: T } - | ~~~~~~ +LL - struct Foo { x: T } +LL + struct Foo { x: T } + | error: aborting due to previous error diff --git a/tests/ui/parser/suggest_misplaced_generics/trait.stderr b/tests/ui/parser/suggest_misplaced_generics/trait.stderr index 069683bda1be3..ac86cfa469704 100644 --- a/tests/ui/parser/suggest_misplaced_generics/trait.stderr +++ b/tests/ui/parser/suggest_misplaced_generics/trait.stderr @@ -6,8 +6,9 @@ LL | trait Foo { | help: place the generic parameter name after the trait name | -LL | trait Foo { - | ~~~~~~ +LL - trait Foo { +LL + trait Foo { + | error: aborting due to previous error diff --git a/tests/ui/parser/suggest_misplaced_generics/type.stderr b/tests/ui/parser/suggest_misplaced_generics/type.stderr index a2832965c6d0e..22744f6cf37fb 100644 --- a/tests/ui/parser/suggest_misplaced_generics/type.stderr +++ b/tests/ui/parser/suggest_misplaced_generics/type.stderr @@ -6,8 +6,9 @@ LL | type Foo = T; | help: place the generic parameter name after the type name | -LL | type Foo = T; - | ~~~~~~ +LL - type Foo = T; +LL + type Foo = T; + | error: aborting due to previous error From a3d32bbbbe06ffe42edbc4905e964d394de5ee02 Mon Sep 17 00:00:00 2001 From: SpanishPear Date: Wed, 1 Feb 2023 18:11:37 +1100 Subject: [PATCH 07/21] fix formatting + test syntax --- compiler/rustc_parse/src/parser/diagnostics.rs | 2 +- tests/ui/parser/suggest_misplaced_generics/enum.fixed | 1 - tests/ui/parser/suggest_misplaced_generics/enum.rs | 1 - .../parser/suggest_misplaced_generics/fn-complex-generics.fixed | 1 - .../ui/parser/suggest_misplaced_generics/fn-complex-generics.rs | 1 - tests/ui/parser/suggest_misplaced_generics/fn-simple.fixed | 1 - tests/ui/parser/suggest_misplaced_generics/fn-simple.rs | 1 - tests/ui/parser/suggest_misplaced_generics/struct.fixed | 1 - tests/ui/parser/suggest_misplaced_generics/struct.rs | 1 - tests/ui/parser/suggest_misplaced_generics/trait.fixed | 1 - tests/ui/parser/suggest_misplaced_generics/trait.rs | 1 - tests/ui/parser/suggest_misplaced_generics/type.fixed | 1 - tests/ui/parser/suggest_misplaced_generics/type.rs | 1 - 13 files changed, 1 insertion(+), 13 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 1740f2c2c8455..2c6db485828bd 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -353,7 +353,7 @@ impl<'a> Parser<'a> { if !self.look_ahead(1, |t| *t == token::Lt) && let Ok(snippet) = self.sess.source_map().span_to_snippet(generic.span) { - err.multipart_suggestion_verbose( + err.multipart_suggestion_verbose( format!("place the generic parameter name after the {ident_name} name"), vec![ (self.token.span.shrink_to_hi(), snippet), diff --git a/tests/ui/parser/suggest_misplaced_generics/enum.fixed b/tests/ui/parser/suggest_misplaced_generics/enum.fixed index a9d3e9f86d09c..3332118a1e768 100644 --- a/tests/ui/parser/suggest_misplaced_generics/enum.fixed +++ b/tests/ui/parser/suggest_misplaced_generics/enum.fixed @@ -5,6 +5,5 @@ enum Foo { Variant(T) } //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the enum name -//~| SUGGESTION Foo fn main() {} diff --git a/tests/ui/parser/suggest_misplaced_generics/enum.rs b/tests/ui/parser/suggest_misplaced_generics/enum.rs index 2d216ba53cc72..5a2289c5c5ae2 100644 --- a/tests/ui/parser/suggest_misplaced_generics/enum.rs +++ b/tests/ui/parser/suggest_misplaced_generics/enum.rs @@ -5,6 +5,5 @@ enum Foo { Variant(T) } //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the enum name -//~| SUGGESTION Foo fn main() {} diff --git a/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed b/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed index 06947e098ee6a..84bf64bd63cf9 100644 --- a/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed +++ b/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.fixed @@ -5,6 +5,5 @@ fn f<'a, B: 'a + std::ops::Add>(_x: B) { } //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the fn name -//~| SUGGESTION f<'a, B: 'a + std::ops::Add> fn main() {} diff --git a/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs b/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs index cefce8d08806d..d0684397e744c 100644 --- a/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs +++ b/tests/ui/parser/suggest_misplaced_generics/fn-complex-generics.rs @@ -5,6 +5,5 @@ fn<'a, B: 'a + std::ops::Add> f(_x: B) { } //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the fn name -//~| SUGGESTION f<'a, B: 'a + std::ops::Add> fn main() {} diff --git a/tests/ui/parser/suggest_misplaced_generics/fn-simple.fixed b/tests/ui/parser/suggest_misplaced_generics/fn-simple.fixed index 31c5429b16b05..cbfd5f2d39c08 100644 --- a/tests/ui/parser/suggest_misplaced_generics/fn-simple.fixed +++ b/tests/ui/parser/suggest_misplaced_generics/fn-simple.fixed @@ -5,6 +5,5 @@ fn id(x: T) -> T { x } //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the fn name -//~| SUGGESTION id fn main() {} diff --git a/tests/ui/parser/suggest_misplaced_generics/fn-simple.rs b/tests/ui/parser/suggest_misplaced_generics/fn-simple.rs index 0a466184e996f..b207cf70d8584 100644 --- a/tests/ui/parser/suggest_misplaced_generics/fn-simple.rs +++ b/tests/ui/parser/suggest_misplaced_generics/fn-simple.rs @@ -5,6 +5,5 @@ fn id(x: T) -> T { x } //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the fn name -//~| SUGGESTION id fn main() {} diff --git a/tests/ui/parser/suggest_misplaced_generics/struct.fixed b/tests/ui/parser/suggest_misplaced_generics/struct.fixed index 8627699a83084..fec05bdeca15c 100644 --- a/tests/ui/parser/suggest_misplaced_generics/struct.fixed +++ b/tests/ui/parser/suggest_misplaced_generics/struct.fixed @@ -5,6 +5,5 @@ struct Foo { x: T } //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the struct name -//~| SUGGESTION Foo fn main() {} diff --git a/tests/ui/parser/suggest_misplaced_generics/struct.rs b/tests/ui/parser/suggest_misplaced_generics/struct.rs index 15646b06cfc62..6b80150d54656 100644 --- a/tests/ui/parser/suggest_misplaced_generics/struct.rs +++ b/tests/ui/parser/suggest_misplaced_generics/struct.rs @@ -5,6 +5,5 @@ struct Foo { x: T } //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the struct name -//~| SUGGESTION Foo fn main() {} diff --git a/tests/ui/parser/suggest_misplaced_generics/trait.fixed b/tests/ui/parser/suggest_misplaced_generics/trait.fixed index 31ebf1f088fc7..a471a078af142 100644 --- a/tests/ui/parser/suggest_misplaced_generics/trait.fixed +++ b/tests/ui/parser/suggest_misplaced_generics/trait.fixed @@ -5,7 +5,6 @@ trait Foo { //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the trait name - //~| SUGGESTION Foo } diff --git a/tests/ui/parser/suggest_misplaced_generics/trait.rs b/tests/ui/parser/suggest_misplaced_generics/trait.rs index 81b6abbd66163..55355f451f9fd 100644 --- a/tests/ui/parser/suggest_misplaced_generics/trait.rs +++ b/tests/ui/parser/suggest_misplaced_generics/trait.rs @@ -5,7 +5,6 @@ trait Foo { //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the trait name - //~| SUGGESTION Foo } diff --git a/tests/ui/parser/suggest_misplaced_generics/type.fixed b/tests/ui/parser/suggest_misplaced_generics/type.fixed index b04003b803d1c..a97b9e66d0b2b 100644 --- a/tests/ui/parser/suggest_misplaced_generics/type.fixed +++ b/tests/ui/parser/suggest_misplaced_generics/type.fixed @@ -5,6 +5,5 @@ type Foo = T; //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the type name -//~| SUGGESTION Foo fn main() {} diff --git a/tests/ui/parser/suggest_misplaced_generics/type.rs b/tests/ui/parser/suggest_misplaced_generics/type.rs index 2d759a8b1ab61..17e200536fa3e 100644 --- a/tests/ui/parser/suggest_misplaced_generics/type.rs +++ b/tests/ui/parser/suggest_misplaced_generics/type.rs @@ -5,6 +5,5 @@ type Foo = T; //~^ ERROR expected identifier, found `<` //~| HELP place the generic parameter name after the type name -//~| SUGGESTION Foo fn main() {} From 44a23888288d680ccfd24409629e184fe8ab95bb Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Jan 2023 13:42:00 -0300 Subject: [PATCH 08/21] Make Ok value of repeat_while_none more general --- .../rustc_trait_selection/src/solve/mod.rs | 51 ++++++++++--------- .../src/solve/search_graph/overflow.rs | 9 ++-- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index e56588c58bd05..e3f8f7cddaba0 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -485,35 +485,38 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { mut goals: Vec>>, ) -> Result { let mut new_goals = Vec::new(); - self.repeat_while_none(|this| { - let mut has_changed = Err(Certainty::Yes); - for goal in goals.drain(..) { - let (changed, certainty) = match this.evaluate_goal(goal) { - Ok(result) => result, - Err(NoSolution) => return Some(Err(NoSolution)), - }; - - if changed { - has_changed = Ok(()); - } + self.repeat_while_none( + |_| Certainty::Maybe(MaybeCause::Overflow), + |this| { + let mut has_changed = Err(Certainty::Yes); + for goal in goals.drain(..) { + let (changed, certainty) = match this.evaluate_goal(goal) { + Ok(result) => result, + Err(NoSolution) => return Some(Err(NoSolution)), + }; + + if changed { + has_changed = Ok(()); + } - match certainty { - Certainty::Yes => {} - Certainty::Maybe(_) => { - new_goals.push(goal); - has_changed = has_changed.map_err(|c| c.unify_and(certainty)); + match certainty { + Certainty::Yes => {} + Certainty::Maybe(_) => { + new_goals.push(goal); + has_changed = has_changed.map_err(|c| c.unify_and(certainty)); + } } } - } - match has_changed { - Ok(()) => { - mem::swap(&mut new_goals, &mut goals); - None + match has_changed { + Ok(()) => { + mem::swap(&mut new_goals, &mut goals); + None + } + Err(certainty) => Some(Ok(certainty)), } - Err(certainty) => Some(Ok(certainty)), - } - }) + }, + ) } // Recursively evaluates a list of goals to completion, making a query response. diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs index 1dd3894c91adc..c472dfe5a009d 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs @@ -63,10 +63,11 @@ impl<'tcx> SearchGraph<'tcx> { impl<'tcx> EvalCtxt<'_, 'tcx> { /// A `while`-loop which tracks overflow. - pub fn repeat_while_none( + pub fn repeat_while_none( &mut self, - mut loop_body: impl FnMut(&mut Self) -> Option>, - ) -> Result { + mut overflow_body: impl FnMut(&mut Self) -> T, + mut loop_body: impl FnMut(&mut Self) -> Option>, + ) -> Result { let start_depth = self.search_graph.overflow_data.additional_depth; let depth = self.search_graph.stack.len(); while !self.search_graph.overflow_data.has_overflow(depth) { @@ -79,6 +80,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } self.search_graph.overflow_data.additional_depth = start_depth; self.search_graph.overflow_data.deal_with_overflow(); - Ok(Certainty::Maybe(MaybeCause::Overflow)) + Ok(overflow_body(self)) } } From 873c83ba56650a32383bb8fb4820a0ce792bc121 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 13 Feb 2023 14:37:46 -0300 Subject: [PATCH 09/21] Extract try_move_finished_goal_to_global_cache from try_finalize_goal --- .../src/solve/search_graph/mod.rs | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index a2ca4bc189c87..c25a9cddfe734 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -133,7 +133,6 @@ impl<'tcx> SearchGraph<'tcx> { let cache = &mut self.provisional_cache; let provisional_entry_index = *cache.lookup_table.get(&goal).unwrap(); let provisional_entry = &mut cache.entries[provisional_entry_index]; - let depth = provisional_entry.depth; // We eagerly update the response in the cache here. If we have to reevaluate // this goal we use the new response when hitting a cycle, and we definitely // want to access the final response whenever we look at the cache. @@ -157,29 +156,41 @@ impl<'tcx> SearchGraph<'tcx> { self.stack.push(StackElem { goal, has_been_used: false }); false } else { - // If not, we're done with this goal. - // - // Check whether that this goal doesn't depend on a goal deeper on the stack - // and if so, move it and all nested goals to the global cache. - // - // Note that if any nested goal were to depend on something deeper on the stack, - // this would have also updated the depth of the current goal. - if depth == self.stack.next_index() { - for (i, entry) in cache.entries.drain_enumerated(provisional_entry_index.index()..) - { - let actual_index = cache.lookup_table.remove(&entry.goal); - debug_assert_eq!(Some(i), actual_index); - debug_assert!(entry.depth == depth); - cache::try_move_finished_goal_to_global_cache( - tcx, - &mut self.overflow_data, - &self.stack, - entry.goal, - entry.response, - ); - } - } + self.try_move_finished_goal_to_global_cache(tcx, &goal); true } } + + pub(super) fn try_move_finished_goal_to_global_cache( + &mut self, + tcx: TyCtxt<'tcx>, + goal: &CanonicalGoal<'tcx>, + ) { + let cache = &mut self.provisional_cache; + let provisional_entry_index = *cache.lookup_table.get(goal).unwrap(); + let provisional_entry = &mut cache.entries[provisional_entry_index]; + let depth = provisional_entry.depth; + + // If not, we're done with this goal. + // + // Check whether that this goal doesn't depend on a goal deeper on the stack + // and if so, move it and all nested goals to the global cache. + // + // Note that if any nested goal were to depend on something deeper on the stack, + // this would have also updated the depth of the current goal. + if depth == self.stack.next_index() { + for (i, entry) in cache.entries.drain_enumerated(provisional_entry_index.index()..) { + let actual_index = cache.lookup_table.remove(&entry.goal); + debug_assert_eq!(Some(i), actual_index); + debug_assert!(entry.depth == depth); + cache::try_move_finished_goal_to_global_cache( + tcx, + &mut self.overflow_data, + &self.stack, + entry.goal, + entry.response, + ); + } + } + } } From 826bee7085620843d184dda382b1aa825fc4b770 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 6 Feb 2023 16:28:27 -0300 Subject: [PATCH 10/21] Implement repeat_while_none for both SearchGraph and EvalCtxt --- .../rustc_trait_selection/src/solve/mod.rs | 1 + .../src/solve/search_graph/mod.rs | 4 +- .../src/solve/search_graph/overflow.rs | 57 ++++++++++++------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index e3f8f7cddaba0..358a2bcc7b9eb 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -31,6 +31,7 @@ use rustc_middle::ty::{ }; use rustc_span::DUMMY_SP; +use crate::solve::search_graph::overflow::OverflowHandler; use crate::traits::ObligationCause; mod assembly; diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index c25a9cddfe734..438bcd9a7d689 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -1,5 +1,5 @@ mod cache; -mod overflow; +pub(crate) mod overflow; use self::cache::ProvisionalEntry; use super::{CanonicalGoal, Certainty, MaybeCause, QueryResult}; @@ -18,7 +18,7 @@ struct StackElem<'tcx> { has_been_used: bool, } -pub(super) struct SearchGraph<'tcx> { +pub(crate) struct SearchGraph<'tcx> { /// The stack of goals currently being computed. /// /// An element is *deeper* in the stack if its index is *lower*. diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs index c472dfe5a009d..0d6863b1e813d 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs @@ -50,36 +50,49 @@ impl OverflowData { } } -impl<'tcx> SearchGraph<'tcx> { - pub fn deal_with_overflow( - &mut self, - tcx: TyCtxt<'tcx>, - goal: Canonical<'tcx, impl Sized>, - ) -> QueryResult<'tcx> { - self.overflow_data.deal_with_overflow(); - response_no_constraints(tcx, goal, Certainty::Maybe(MaybeCause::Overflow)) - } -} +pub(crate) trait OverflowHandler<'tcx> { + fn search_graph(&mut self) -> &mut SearchGraph<'tcx>; -impl<'tcx> EvalCtxt<'_, 'tcx> { - /// A `while`-loop which tracks overflow. - pub fn repeat_while_none( + fn repeat_while_none( &mut self, - mut overflow_body: impl FnMut(&mut Self) -> T, + on_overflow: impl FnOnce(&mut Self) -> T, mut loop_body: impl FnMut(&mut Self) -> Option>, ) -> Result { - let start_depth = self.search_graph.overflow_data.additional_depth; - let depth = self.search_graph.stack.len(); - while !self.search_graph.overflow_data.has_overflow(depth) { + let start_depth = self.search_graph().overflow_data.additional_depth; + let depth = self.search_graph().stack.len(); + while !self.search_graph().overflow_data.has_overflow(depth) { if let Some(result) = loop_body(self) { - self.search_graph.overflow_data.additional_depth = start_depth; + self.search_graph().overflow_data.additional_depth = start_depth; return result; } - self.search_graph.overflow_data.additional_depth += 1; + self.search_graph().overflow_data.additional_depth += 1; } - self.search_graph.overflow_data.additional_depth = start_depth; - self.search_graph.overflow_data.deal_with_overflow(); - Ok(overflow_body(self)) + self.search_graph().overflow_data.additional_depth = start_depth; + self.search_graph().overflow_data.deal_with_overflow(); + Ok(on_overflow(self)) + } +} + +impl<'tcx> OverflowHandler<'tcx> for EvalCtxt<'_, 'tcx> { + fn search_graph(&mut self) -> &mut SearchGraph<'tcx> { + &mut self.search_graph + } +} + +impl<'tcx> OverflowHandler<'tcx> for SearchGraph<'tcx> { + fn search_graph(&mut self) -> &mut SearchGraph<'tcx> { + self + } +} + +impl<'tcx> SearchGraph<'tcx> { + pub fn deal_with_overflow( + &mut self, + tcx: TyCtxt<'tcx>, + goal: Canonical<'tcx, impl Sized>, + ) -> QueryResult<'tcx> { + self.overflow_data.deal_with_overflow(); + response_no_constraints(tcx, goal, Certainty::Maybe(MaybeCause::Overflow)) } } From ef6a59b7a921af918ea5e87ecd9d736899c9161b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 14 Feb 2023 01:43:41 +0200 Subject: [PATCH 11/21] "Basic usage" is redundant for there is just one example --- library/core/src/ptr/const_ptr.rs | 20 -------------------- library/core/src/ptr/mut_ptr.rs | 22 ---------------------- 2 files changed, 42 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 16eb726f6f614..57e2ffe5d2068 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -23,8 +23,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let s: &str = "Follow the rabbit"; /// let ptr: *const u8 = s.as_ptr(); @@ -323,8 +321,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let ptr: *const u8 = &10u8 as *const u8; /// @@ -384,8 +380,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// #![feature(ptr_as_uninit)] /// @@ -449,8 +443,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let s: &str = "123"; /// let ptr: *const u8 = s.as_ptr(); @@ -526,8 +518,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// // Iterate using a raw pointer in increments of two elements /// let data = [1u8, 2, 3, 4, 5]; @@ -908,8 +898,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let s: &str = "123"; /// let ptr: *const u8 = s.as_ptr(); @@ -993,8 +981,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let s: &str = "123"; /// @@ -1072,8 +1058,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// // Iterate using a raw pointer in increments of two elements /// let data = [1u8, 2, 3, 4, 5]; @@ -1152,8 +1136,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// // Iterate using a raw pointer in increments of two elements (backwards) /// let data = [1u8, 2, 3, 4, 5]; @@ -1359,7 +1341,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: /// ``` /// #![feature(pointer_is_aligned)] /// #![feature(pointer_byte_offsets)] @@ -1482,7 +1463,6 @@ impl *const T { /// /// # Examples /// - /// Basic usage: /// ``` /// #![feature(pointer_is_aligned)] /// #![feature(pointer_byte_offsets)] diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 0a2f63e3ec6a5..422d0f2b8f0c4 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -22,8 +22,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let mut s = [1, 2, 3]; /// let ptr: *mut u32 = s.as_mut_ptr(); @@ -332,8 +330,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let ptr: *mut u8 = &mut 10u8 as *mut u8; /// @@ -396,8 +392,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// #![feature(ptr_as_uninit)] /// @@ -461,8 +455,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let mut s = [1, 2, 3]; /// let ptr: *mut u32 = s.as_mut_ptr(); @@ -539,8 +531,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// // Iterate using a raw pointer in increments of two elements /// let mut data = [1u8, 2, 3, 4, 5]; @@ -660,8 +650,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let mut s = [1, 2, 3]; /// let ptr: *mut u32 = s.as_mut_ptr(); @@ -1010,8 +998,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let s: &str = "123"; /// let ptr: *const u8 = s.as_ptr(); @@ -1095,8 +1081,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// let s: &str = "123"; /// @@ -1174,8 +1158,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// // Iterate using a raw pointer in increments of two elements /// let data = [1u8, 2, 3, 4, 5]; @@ -1254,8 +1236,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: - /// /// ``` /// // Iterate using a raw pointer in increments of two elements (backwards) /// let data = [1u8, 2, 3, 4, 5]; @@ -1627,7 +1607,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: /// ``` /// #![feature(pointer_is_aligned)] /// #![feature(pointer_byte_offsets)] @@ -1752,7 +1731,6 @@ impl *mut T { /// /// # Examples /// - /// Basic usage: /// ``` /// #![feature(pointer_is_aligned)] /// #![feature(pointer_byte_offsets)] From 3180f1c828636a247777d277f10c9695d7141d20 Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 13 Feb 2023 17:20:38 +0000 Subject: [PATCH 12/21] Fix #107998, avoid ICE when the generic_span is empty --- compiler/rustc_lint/src/context.rs | 10 ++++++- tests/ui/single-use-lifetime/issue-107998.rs | 9 ++++++ .../single-use-lifetime/issue-107998.stderr | 30 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/ui/single-use-lifetime/issue-107998.rs create mode 100644 tests/ui/single-use-lifetime/issue-107998.stderr diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index d1d4bb375282f..972240f42cf46 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -837,9 +837,17 @@ pub trait LintContext: Sized { (use_span, "'_".to_owned()) }; debug!(?deletion_span, ?use_span); + + // issue 107998 for the case such as a wrong function pointer type + // `deletion_span` is empty and there is no need to report lifetime uses here + let suggestions = if deletion_span.is_empty() { + vec![(use_span, replace_lt)] + } else { + vec![(deletion_span, String::new()), (use_span, replace_lt)] + }; db.multipart_suggestion( msg, - vec![(deletion_span, String::new()), (use_span, replace_lt)], + suggestions, Applicability::MachineApplicable, ); } diff --git a/tests/ui/single-use-lifetime/issue-107998.rs b/tests/ui/single-use-lifetime/issue-107998.rs new file mode 100644 index 0000000000000..f32688d205813 --- /dev/null +++ b/tests/ui/single-use-lifetime/issue-107998.rs @@ -0,0 +1,9 @@ +#![deny(single_use_lifetimes)] + +fn with(f: &fn<'a>(x: &'a i32) -> R) -> R { + //~^ ERROR function pointer types may not have generic parameters + //~| ERROR lifetime parameter `'a` only used once + f(&3) +} + +fn main() {} diff --git a/tests/ui/single-use-lifetime/issue-107998.stderr b/tests/ui/single-use-lifetime/issue-107998.stderr new file mode 100644 index 0000000000000..e870351de9eae --- /dev/null +++ b/tests/ui/single-use-lifetime/issue-107998.stderr @@ -0,0 +1,30 @@ +error: function pointer types may not have generic parameters + --> $DIR/issue-107998.rs:3:18 + | +LL | fn with(f: &fn<'a>(x: &'a i32) -> R) -> R { + | ^^^^ + | +help: consider moving the lifetime parameter to a `for` parameter list + | +LL - fn with(f: &fn<'a>(x: &'a i32) -> R) -> R { +LL + fn with(f: &for<'a> fn(x: &'a i32) -> R) -> R { + | + +error: lifetime parameter `'a` only used once + --> $DIR/issue-107998.rs:3:19 + | +LL | fn with(f: &fn<'a>(x: &'a i32) -> R) -> R { + | ^^ --- + | | | + | | ...is used only here + | | help: elide the single-use lifetime + | this lifetime... + | +note: the lint level is defined here + --> $DIR/issue-107998.rs:1:9 + | +LL | #![deny(single_use_lifetimes)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 826abcc72803fce26bcce574ace5ee6c4bbc936f Mon Sep 17 00:00:00 2001 From: kadmin Date: Tue, 14 Feb 2023 05:01:24 +0000 Subject: [PATCH 13/21] Shrink size of array benchmarks --- library/core/benches/array.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/benches/array.rs b/library/core/benches/array.rs index 845c60762949b..d8cc44d05c4ba 100644 --- a/library/core/benches/array.rs +++ b/library/core/benches/array.rs @@ -11,9 +11,9 @@ macro_rules! map_array { }; } -map_array!(map_8byte_8byte_8, 0u64, 1u64, 800); -map_array!(map_8byte_8byte_64, 0u64, 1u64, 6400); -map_array!(map_8byte_8byte_256, 0u64, 1u64, 25600); +map_array!(map_8byte_8byte_8, 0u64, 1u64, 80); +map_array!(map_8byte_8byte_64, 0u64, 1u64, 640); +map_array!(map_8byte_8byte_256, 0u64, 1u64, 2560); -map_array!(map_8byte_256byte_256, 0u64, [0u64; 4], 25600); -map_array!(map_256byte_8byte_256, [0u64; 4], 0u64, 25600); +map_array!(map_8byte_256byte_256, 0u64, [0u64; 4], 2560); +map_array!(map_256byte_8byte_256, [0u64; 4], 0u64, 2560); From 2a5a1a89d354ed6f660e63fb95c86ffe9e3676f3 Mon Sep 17 00:00:00 2001 From: Zephaniah Ong Date: Tue, 14 Feb 2023 13:56:19 +0800 Subject: [PATCH 14/21] add message to update Cargo.toml when x is changed --- triagebot.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 62a99b704388f..8d7e237e44d81 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -468,6 +468,9 @@ This was probably unintentional and should be reverted before this PR is merged. If this was intentional then you can ignore this comment. """ +[mentions."src/tools/x/src/main.rs"] +message = "`src/tools/x/src/main.rs` was changed. Bump version of Cargo.toml in `src/tools/x` ." + [assign] warn_non_default_branch = true contributing_url = "https://rustc-dev-guide.rust-lang.org/contributing.html" From ba4b026e80c6278b6d0d8d4b4bf66daf4f49ed09 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 13 Feb 2023 22:57:28 -0700 Subject: [PATCH 15/21] rustdoc: add more tooltips to intra-doc links This commit makes intra-doc link tooltips consistent with generated links in function signatures and item tables, with the format `itemtype foo::bar::baz`. This way, you can tell if a link points at a trait or a type (for example) by mousing over it. See also fce944d4e79b3a87ddf511206724edf33acfd704 --- src/librustdoc/clean/types.rs | 12 ++++++++---- src/librustdoc/html/format.rs | 16 ++++++++++++++++ src/librustdoc/html/markdown.rs | 16 +++++++++++----- tests/rustdoc/intra-doc/basic.rs | 17 +++++++++++++++++ 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index ffe6fea7ea447..b00cefdddb524 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -482,16 +482,16 @@ impl Item { } pub(crate) fn links(&self, cx: &Context<'_>) -> Vec { - use crate::html::format::href; + use crate::html::format::{href, link_tooltip}; cx.cache() .intra_doc_links .get(&self.item_id) .map_or(&[][..], |v| v.as_slice()) .iter() - .filter_map(|ItemLink { link: s, link_text, page_id: did, ref fragment }| { - debug!(?did); - if let Ok((mut href, ..)) = href(*did, cx) { + .filter_map(|ItemLink { link: s, link_text, page_id: id, ref fragment }| { + debug!(?id); + if let Ok((mut href, ..)) = href(*id, cx) { debug!(?href); if let Some(ref fragment) = *fragment { fragment.render(&mut href, cx.tcx()) @@ -499,6 +499,7 @@ impl Item { Some(RenderedLink { original_text: s.clone(), new_text: link_text.clone(), + tooltip: link_tooltip(*id, fragment, cx), href, }) } else { @@ -523,6 +524,7 @@ impl Item { original_text: s.clone(), new_text: link_text.clone(), href: String::new(), + tooltip: String::new(), }) .collect() } @@ -1040,6 +1042,8 @@ pub struct RenderedLink { pub(crate) new_text: String, /// The URL to put in the `href` pub(crate) href: String, + /// The tooltip. + pub(crate) tooltip: String, } /// The attributes on an [`Item`], including attributes like `#[derive(...)]` and `#[inline]`, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 8a7a8ea5fd1f2..314f061224940 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -34,6 +34,7 @@ use crate::clean::{ use crate::formats::item_type::ItemType; use crate::html::escape::Escape; use crate::html::render::Context; +use crate::passes::collect_intra_doc_links::UrlFragment; use super::url_parts_builder::estimate_item_path_byte_length; use super::url_parts_builder::UrlPartsBuilder; @@ -768,6 +769,21 @@ pub(crate) fn href_relative_parts<'fqp>( } } +pub(crate) fn link_tooltip(did: DefId, fragment: &Option, cx: &Context<'_>) -> String { + let cache = cx.cache(); + let Some((fqp, shortty)) = cache.paths.get(&did) + .or_else(|| cache.external_paths.get(&did)) + else { return String::new() }; + let fqp = fqp.iter().map(|sym| sym.as_str()).join("::"); + if let &Some(UrlFragment::Item(id)) = fragment { + let name = cx.tcx().item_name(id); + let descr = cx.tcx().def_kind(id).descr(id); + format!("{descr} {fqp}::{name}") + } else { + format!("{shortty} {fqp}") + } +} + /// Used to render a [`clean::Path`]. fn resolved_path<'cx>( w: &mut fmt::Formatter<'_>, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 331804393938f..e4adee6ae4dfb 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -360,6 +360,9 @@ impl<'a, I: Iterator>> Iterator for LinkReplacer<'a, I> { trace!("it matched"); assert!(self.shortcut_link.is_none(), "shortcut links cannot be nested"); self.shortcut_link = Some(link); + if title.is_empty() && !link.tooltip.is_empty() { + *title = CowStr::Borrowed(link.tooltip.as_ref()); + } } } // Now that we're done with the shortcut link, don't replace any more text. @@ -410,9 +413,12 @@ impl<'a, I: Iterator>> Iterator for LinkReplacer<'a, I> { } // If this is a link, but not a shortcut link, // replace the URL, since the broken_link_callback was not called. - Some(Event::Start(Tag::Link(_, dest, _))) => { + Some(Event::Start(Tag::Link(_, dest, title))) => { if let Some(link) = self.links.iter().find(|&link| *link.original_text == **dest) { *dest = CowStr::Borrowed(link.href.as_ref()); + if title.is_empty() && !link.tooltip.is_empty() { + *title = CowStr::Borrowed(link.tooltip.as_ref()); + } } } // Anything else couldn't have been a valid Rust path, so no need to replace the text. @@ -976,7 +982,7 @@ impl Markdown<'_> { links .iter() .find(|link| link.original_text.as_str() == &*broken_link.reference) - .map(|link| (link.href.as_str().into(), link.new_text.as_str().into())) + .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) }; let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut replacer)); @@ -1059,7 +1065,7 @@ impl MarkdownSummaryLine<'_> { links .iter() .find(|link| link.original_text.as_str() == &*broken_link.reference) - .map(|link| (link.href.as_str().into(), link.new_text.as_str().into())) + .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) }; let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer)) @@ -1106,7 +1112,7 @@ fn markdown_summary_with_limit( link_names .iter() .find(|link| link.original_text.as_str() == &*broken_link.reference) - .map(|link| (link.href.as_str().into(), link.new_text.as_str().into())) + .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) }; let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer)); @@ -1187,7 +1193,7 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin link_names .iter() .find(|link| link.original_text.as_str() == &*broken_link.reference) - .map(|link| (link.href.as_str().into(), link.new_text.as_str().into())) + .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) }; let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer)); diff --git a/tests/rustdoc/intra-doc/basic.rs b/tests/rustdoc/intra-doc/basic.rs index 39f5c298bc4a1..e2d3ef425cb45 100644 --- a/tests/rustdoc/intra-doc/basic.rs +++ b/tests/rustdoc/intra-doc/basic.rs @@ -1,21 +1,38 @@ // @has basic/index.html // @has - '//a/@href' 'struct.ThisType.html' +// @has - '//a/@title' 'struct basic::ThisType' // @has - '//a/@href' 'struct.ThisType.html#method.this_method' +// @has - '//a/@title' 'associated function basic::ThisType::this_method' // @has - '//a/@href' 'enum.ThisEnum.html' +// @has - '//a/@title' 'enum basic::ThisEnum' // @has - '//a/@href' 'enum.ThisEnum.html#variant.ThisVariant' +// @has - '//a/@title' 'variant basic::ThisEnum::ThisVariant' // @has - '//a/@href' 'trait.ThisTrait.html' +// @has - '//a/@title' 'trait basic::ThisTrait' // @has - '//a/@href' 'trait.ThisTrait.html#tymethod.this_associated_method' +// @has - '//a/@title' 'associated function basic::ThisTrait::this_associated_method' // @has - '//a/@href' 'trait.ThisTrait.html#associatedtype.ThisAssociatedType' +// @has - '//a/@title' 'associated type basic::ThisTrait::ThisAssociatedType' // @has - '//a/@href' 'trait.ThisTrait.html#associatedconstant.THIS_ASSOCIATED_CONST' +// @has - '//a/@title' 'associated constant basic::ThisTrait::THIS_ASSOCIATED_CONST' // @has - '//a/@href' 'trait.ThisTrait.html' +// @has - '//a/@title' 'trait basic::ThisTrait' // @has - '//a/@href' 'type.ThisAlias.html' +// @has - '//a/@title' 'type basic::ThisAlias' // @has - '//a/@href' 'union.ThisUnion.html' +// @has - '//a/@title' 'union basic::ThisUnion' // @has - '//a/@href' 'fn.this_function.html' +// @has - '//a/@title' 'fn basic::this_function' // @has - '//a/@href' 'constant.THIS_CONST.html' +// @has - '//a/@title' 'constant basic::THIS_CONST' // @has - '//a/@href' 'static.THIS_STATIC.html' +// @has - '//a/@title' 'static basic::THIS_STATIC' // @has - '//a/@href' 'macro.this_macro.html' +// @has - '//a/@title' 'macro basic::this_macro' // @has - '//a/@href' 'trait.SoAmbiguous.html' +// @has - '//a/@title' 'trait basic::SoAmbiguous' // @has - '//a/@href' 'fn.SoAmbiguous.html' +// @has - '//a/@title' 'fn basic::SoAmbiguous' //! In this crate we would like to link to: //! //! * [`ThisType`](ThisType) From 70fd729e7eac7f3801a29e6e00dafd04516d63e7 Mon Sep 17 00:00:00 2001 From: Zephaniah Ong Date: Tue, 14 Feb 2023 14:25:46 +0800 Subject: [PATCH 16/21] change file path and improve message --- triagebot.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 8d7e237e44d81..883bc8720e2be 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -468,8 +468,8 @@ This was probably unintentional and should be reverted before this PR is merged. If this was intentional then you can ignore this comment. """ -[mentions."src/tools/x/src/main.rs"] -message = "`src/tools/x/src/main.rs` was changed. Bump version of Cargo.toml in `src/tools/x` ." +[mentions."src/tools/x"] +message = "`src/tools/x` was changed. Bump version of Cargo.toml in `src/tools/x` so tidy will suggest installing the new version." [assign] warn_non_default_branch = true From 936bf29d4cec40c328930daf83277d7e77cc9602 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 14 Feb 2023 08:51:19 +0000 Subject: [PATCH 17/21] s/eval_usize/eval_target_usize/ for clarity --- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- compiler/rustc_codegen_cranelift/src/base.rs | 2 +- .../src/intrinsics/simd.rs | 4 +- .../rustc_codegen_cranelift/src/unsize.rs | 2 +- .../src/value_and_place.rs | 4 +- .../rustc_codegen_gcc/src/intrinsic/simd.rs | 407 ++++++++++-------- .../src/debuginfo/metadata.rs | 2 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 10 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- .../src/debuginfo/type_names.rs | 16 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 7 +- .../rustc_const_eval/src/const_eval/mod.rs | 2 +- .../rustc_const_eval/src/interpret/cast.rs | 7 +- .../src/transform/check_consts/check.rs | 2 +- .../src/transform/promote_consts.rs | 36 +- .../rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 6 +- .../src/generator_interior/mod.rs | 3 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/unused.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 8 +- compiler/rustc_middle/src/mir/tcx.rs | 2 +- compiler/rustc_middle/src/ty/consts.rs | 12 +- compiler/rustc_middle/src/ty/context.rs | 2 +- .../ty/inhabitedness/inhabited_predicate.rs | 2 +- compiler/rustc_middle/src/ty/relate.rs | 4 +- compiler/rustc_middle/src/ty/sty.rs | 2 +- .../src/build/expr/as_rvalue.rs | 2 +- .../rustc_mir_build/src/build/matches/util.rs | 2 +- .../src/thir/pattern/deconstruct_pat.rs | 8 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 2 +- .../rustc_mir_dataflow/src/elaborate_drops.rs | 2 +- .../src/move_paths/builder.rs | 4 +- compiler/rustc_mir_transform/src/generator.rs | 2 +- .../rustc_mir_transform/src/large_enums.rs | 2 +- .../src/traits/structural_match.rs | 2 +- compiler/rustc_transmute/src/layout/tree.rs | 5 +- compiler/rustc_ty_utils/src/layout.rs | 3 +- .../clippy_lints/src/indexing_slicing.rs | 2 +- .../src/loops/explicit_iter_loop.rs | 2 +- .../src/loops/needless_range_loop.rs | 2 +- .../clippy/clippy_lints/src/methods/utils.rs | 2 +- src/tools/clippy/clippy_lints/src/mut_key.rs | 2 +- .../clippy_lints/src/trailing_empty_array.rs | 2 +- src/tools/clippy/clippy_utils/src/consts.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- src/tools/miri/src/shims/intrinsics/simd.rs | 2 +- 48 files changed, 347 insertions(+), 259 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 64c96281ed983..5b7adae66acf7 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1782,7 +1782,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // than 1. // If the length is larger than 1, the repeat expression will need to copy the // element, so we require the `Copy` trait. - if len.try_eval_usize(tcx, self.param_env).map_or(true, |len| len > 1) { + if len.try_eval_target_usize(tcx, self.param_env).map_or(true, |len| len > 1) { match operand { Operand::Copy(..) | Operand::Constant(..) => { // These are always okay: direct use of a const, or a value that can evidently be copied. diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 189d952a92f17..95778de3abafc 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -857,7 +857,7 @@ fn codegen_stmt<'tcx>( fn codegen_array_len<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>) -> Value { match *place.layout().ty.kind() { ty::Array(_elem_ty, len) => { - let len = fx.monomorphize(len).eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64; + let len = fx.monomorphize(len).eval_target_usize(fx.tcx, ParamEnv::reveal_all()) as i64; fx.bcx.ins().iconst(fx.pointer_type, len) } ty::Slice(_elem_ty) => { diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index b33eb29754ab7..a1d63acfb6166 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -141,7 +141,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let idx_ty = fx.monomorphize(idx.ty(fx.mir, fx.tcx)); match idx_ty.kind() { ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => len - .try_eval_usize(fx.tcx, ty::ParamEnv::reveal_all()) + .try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all()) .unwrap_or_else(|| { span_bug!(span, "could not evaluate shuffle index array length") }) @@ -735,7 +735,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => {} ty::Array(elem, len) if matches!(elem.kind(), ty::Uint(ty::UintTy::U8)) - && len.try_eval_usize(fx.tcx, ty::ParamEnv::reveal_all()) + && len.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all()) == Some(expected_bytes) => {} _ => { fx.tcx.sess.span_fatal( diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index 9c88f7dbcda33..a0745582d6669 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -24,7 +24,7 @@ pub(crate) fn unsized_info<'tcx>( (&ty::Array(_, len), &ty::Slice(_)) => fx .bcx .ins() - .iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64), + .iconst(fx.pointer_type, len.eval_target_usize(fx.tcx, ParamEnv::reveal_all()) as i64), ( &ty::Dynamic(ref data_a, _, src_dyn_kind), &ty::Dynamic(ref data_b, _, target_dyn_kind), diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 320eecaee008e..cc1edaa97d800 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -564,8 +564,8 @@ impl<'tcx> CPlace<'tcx> { CPlaceInner::Var(_local, var) => { if let ty::Array(element, len) = dst_layout.ty.kind() { // Can only happen for vector types - let len = - u32::try_from(len.eval_usize(fx.tcx, ParamEnv::reveal_all())).unwrap(); + let len = u32::try_from(len.eval_target_usize(fx.tcx, ParamEnv::reveal_all())) + .unwrap(); let vector_ty = fx.clif_type(*element).unwrap().by(len).unwrap(); let data = match from.0 { diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 12e416f62a4e0..cb8168b407184 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; -use gccjit::{BinaryOp, RValue, Type, ToRValue}; +use gccjit::{BinaryOp, RValue, ToRValue, Type}; use rustc_codegen_ssa::base::compare_simd_types; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::mir::operand::OperandRef; @@ -10,52 +10,57 @@ use rustc_hir as hir; use rustc_middle::span_bug; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, Ty}; -use rustc_span::{Span, Symbol, sym}; +use rustc_span::{sym, Span, Symbol}; use rustc_target::abi::Align; use crate::builder::Builder; use crate::errors::{ - InvalidMonomorphizationInvalidFloatVector, - InvalidMonomorphizationNotFloat, - InvalidMonomorphizationUnrecognized, - InvalidMonomorphizationExpectedSignedUnsigned, - InvalidMonomorphizationUnsupportedElement, - InvalidMonomorphizationInvalidBitmask, - InvalidMonomorphizationSimdShuffle, - InvalidMonomorphizationExpectedSimd, - InvalidMonomorphizationMaskType, - InvalidMonomorphizationReturnLength, - InvalidMonomorphizationReturnLengthInputType, - InvalidMonomorphizationReturnElement, - InvalidMonomorphizationReturnType, - InvalidMonomorphizationInsertedType, - InvalidMonomorphizationReturnIntegerType, - InvalidMonomorphizationMismatchedLengths, - InvalidMonomorphizationUnsupportedCast, - InvalidMonomorphizationUnsupportedOperation + InvalidMonomorphizationExpectedSignedUnsigned, InvalidMonomorphizationExpectedSimd, + InvalidMonomorphizationInsertedType, InvalidMonomorphizationInvalidBitmask, + InvalidMonomorphizationInvalidFloatVector, InvalidMonomorphizationMaskType, + InvalidMonomorphizationMismatchedLengths, InvalidMonomorphizationNotFloat, + InvalidMonomorphizationReturnElement, InvalidMonomorphizationReturnIntegerType, + InvalidMonomorphizationReturnLength, InvalidMonomorphizationReturnLengthInputType, + InvalidMonomorphizationReturnType, InvalidMonomorphizationSimdShuffle, + InvalidMonomorphizationUnrecognized, InvalidMonomorphizationUnsupportedCast, + InvalidMonomorphizationUnsupportedElement, InvalidMonomorphizationUnsupportedOperation, }; use crate::intrinsic; -pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, name: Symbol, callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx, RValue<'gcc>>], ret_ty: Ty<'tcx>, llret_ty: Type<'gcc>, span: Span) -> Result, ()> { +pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( + bx: &mut Builder<'a, 'gcc, 'tcx>, + name: Symbol, + callee_ty: Ty<'tcx>, + args: &[OperandRef<'tcx, RValue<'gcc>>], + ret_ty: Ty<'tcx>, + llret_ty: Type<'gcc>, + span: Span, +) -> Result, ()> { // macros for error handling: macro_rules! return_error { - ($err:expr) => { - { - bx.sess().emit_err($err); - return Err(()); - } - } + ($err:expr) => {{ + bx.sess().emit_err($err); + return Err(()); + }}; } macro_rules! require { ($cond:expr, $err:expr) => { if !$cond { return_error!($err); } - } + }; } macro_rules! require_simd { ($ty: expr, $position: expr) => { - require!($ty.is_simd(), InvalidMonomorphizationExpectedSimd { span, name, position: $position, found_ty: $ty }) + require!( + $ty.is_simd(), + InvalidMonomorphizationExpectedSimd { + span, + name, + position: $position, + found_ty: $ty + } + ) }; } @@ -77,7 +82,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(), ty::Array(elem, len) if matches!(elem.kind(), ty::Uint(ty::UintTy::U8)) - && len.try_eval_usize(bx.tcx, ty::ParamEnv::reveal_all()) + && len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all()) == Some(expected_bytes) => { let place = PlaceRef::alloca(bx, args[0].layout); @@ -86,9 +91,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let ptr = bx.pointercast(place.llval, bx.cx.type_ptr_to(int_ty)); bx.load(int_ty, ptr, Align::ONE) } - _ => return_error!( - InvalidMonomorphizationInvalidBitmask { span, name, ty: mask_ty, expected_int_bits, expected_bytes } - ), + _ => return_error!(InvalidMonomorphizationInvalidBitmask { + span, + name, + ty: mask_ty, + expected_int_bits, + expected_bytes + }), }; let arg1 = args[1].immediate(); @@ -129,11 +138,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len } + InvalidMonomorphizationReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } ); require!( bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer, - InvalidMonomorphizationReturnIntegerType {span, name, ret_ty, out_ty} + InvalidMonomorphizationReturnIntegerType { span, name, ret_ty, out_ty } ); return Ok(compare_simd_types( @@ -147,26 +163,26 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, } if let Some(stripped) = name.as_str().strip_prefix("simd_shuffle") { - let n: u64 = - if stripped.is_empty() { - // Make sure this is actually an array, since typeck only checks the length-suffixed - // version of this intrinsic. - match args[2].layout.ty.kind() { - ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => { - len.try_eval_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| { - span_bug!(span, "could not evaluate shuffle index array length") - }) - } - _ => return_error!( - InvalidMonomorphizationSimdShuffle { span, name, ty: args[2].layout.ty } - ), + let n: u64 = if stripped.is_empty() { + // Make sure this is actually an array, since typeck only checks the length-suffixed + // version of this intrinsic. + match args[2].layout.ty.kind() { + ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => { + len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else( + || span_bug!(span, "could not evaluate shuffle index array length"), + ) } + _ => return_error!(InvalidMonomorphizationSimdShuffle { + span, + name, + ty: args[2].layout.ty + }), } - else { - stripped.parse().unwrap_or_else(|_| { - span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") - }) - }; + } else { + stripped.parse().unwrap_or_else(|_| { + span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") + }) + }; require_simd!(ret_ty, "return"); @@ -182,14 +198,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let vector = args[2].immediate(); - return Ok(bx.shuffle_vector( - args[0].immediate(), - args[1].immediate(), - vector, - )); + return Ok(bx.shuffle_vector(args[0].immediate(), args[1].immediate(), vector)); } - #[cfg(feature="master")] + #[cfg(feature = "master")] if name == sym::simd_insert { require!( in_elem == arg_tys[2], @@ -205,44 +217,44 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, // not be an l-value. So, call a builtin to set the element. // TODO(antoyo): perhaps we could create a new vector or maybe there's a GIMPLE instruction for that? // TODO(antoyo): don't use target specific builtins here. - let func_name = - match in_len { - 2 => { - if element_type == bx.i64_type { - "__builtin_ia32_vec_set_v2di" - } - else { - unimplemented!(); - } - }, - 4 => { - if element_type == bx.i32_type { - "__builtin_ia32_vec_set_v4si" - } - else { - unimplemented!(); - } - }, - 8 => { - if element_type == bx.i16_type { - "__builtin_ia32_vec_set_v8hi" - } - else { - unimplemented!(); - } - }, - _ => unimplemented!("Len: {}", in_len), - }; + let func_name = match in_len { + 2 => { + if element_type == bx.i64_type { + "__builtin_ia32_vec_set_v2di" + } else { + unimplemented!(); + } + } + 4 => { + if element_type == bx.i32_type { + "__builtin_ia32_vec_set_v4si" + } else { + unimplemented!(); + } + } + 8 => { + if element_type == bx.i16_type { + "__builtin_ia32_vec_set_v8hi" + } else { + unimplemented!(); + } + } + _ => unimplemented!("Len: {}", in_len), + }; let builtin = bx.context.get_target_builtin_function(func_name); let param1_type = builtin.get_param(0).to_rvalue().get_type(); // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. let vector = bx.cx.bitcast_if_needed(vector, param1_type); - let result = bx.context.new_call(None, builtin, &[vector, value, bx.context.new_cast(None, index, bx.int_type)]); + let result = bx.context.new_call( + None, + builtin, + &[vector, value, bx.context.new_cast(None, index, bx.int_type)], + ); // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. return Ok(bx.context.new_bitcast(None, result, vector.get_type())); } - #[cfg(feature="master")] + #[cfg(feature = "master")] if name == sym::simd_extract { require!( ret_ty == in_elem, @@ -273,7 +285,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len } + InvalidMonomorphizationReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } ); // casting cares about nominal type, not just structural type if in_elem == out_elem { @@ -322,19 +341,27 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let cast_vec_element = |index| { let index = bx.context.new_rvalue_from_int(bx.int_type, index); - bx.context.new_cast(None, bx.context.new_array_access(None, array, index).to_rvalue(), out_type) + bx.context.new_cast( + None, + bx.context.new_array_access(None, array, index).to_rvalue(), + out_type, + ) }; - bx.context.new_rvalue_from_vector(None, vector_type, &[ - cast_vec_element(0), - cast_vec_element(1), - cast_vec_element(2), - cast_vec_element(3), - cast_vec_element(4), - cast_vec_element(5), - cast_vec_element(6), - cast_vec_element(7), - ]) + bx.context.new_rvalue_from_vector( + None, + vector_type, + &[ + cast_vec_element(0), + cast_vec_element(1), + cast_vec_element(2), + cast_vec_element(3), + cast_vec_element(4), + cast_vec_element(5), + cast_vec_element(6), + cast_vec_element(7), + ], + ) }; match (in_style, out_style) { @@ -385,9 +412,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, } _ => { /* Unsupported. Fallthrough. */ } } - return_error!( - InvalidMonomorphizationUnsupportedCast { span, name, in_ty, in_elem, ret_ty, out_elem } - ); + return_error!(InvalidMonomorphizationUnsupportedCast { + span, + name, + in_ty, + in_elem, + ret_ty, + out_elem + }); } macro_rules! arith_binary { @@ -414,54 +446,60 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, args: &[OperandRef<'tcx, RValue<'gcc>>], ) -> Result, ()> { macro_rules! return_error { - ($err:expr) => { - { - bx.sess().emit_err($err); - return Err(()); - } - } + ($err:expr) => {{ + bx.sess().emit_err($err); + return Err(()); + }}; } - let (elem_ty_str, elem_ty) = - if let ty::Float(f) = in_elem.kind() { - let elem_ty = bx.cx.type_float_from_ty(*f); - match f.bit_width() { - 32 => ("f32", elem_ty), - 64 => ("f64", elem_ty), - _ => { - return_error!(InvalidMonomorphizationInvalidFloatVector { span, name, elem_ty: f.name_str(), vec_ty: in_ty }); - } + let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() { + let elem_ty = bx.cx.type_float_from_ty(*f); + match f.bit_width() { + 32 => ("f32", elem_ty), + 64 => ("f64", elem_ty), + _ => { + return_error!(InvalidMonomorphizationInvalidFloatVector { + span, + name, + elem_ty: f.name_str(), + vec_ty: in_ty + }); } } - else { - return_error!(InvalidMonomorphizationNotFloat { span, name, ty: in_ty }); - }; + } else { + return_error!(InvalidMonomorphizationNotFloat { span, name, ty: in_ty }); + }; let vec_ty = bx.cx.type_vector(elem_ty, in_len); - let (intr_name, fn_ty) = - match name { - sym::simd_ceil => ("ceil", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_fabs => ("fabs", bx.type_func(&[vec_ty], vec_ty)), // TODO(antoyo): pand with 170141183420855150465331762880109871103 - sym::simd_fcos => ("cos", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_fexp2 => ("exp2", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_fexp => ("exp", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_flog10 => ("log10", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_flog2 => ("log2", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_flog => ("log", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)), - sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)), - sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)), - sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), - sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)), - _ => return_error!(InvalidMonomorphizationUnrecognized { span, name }) - }; + let (intr_name, fn_ty) = match name { + sym::simd_ceil => ("ceil", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fabs => ("fabs", bx.type_func(&[vec_ty], vec_ty)), // TODO(antoyo): pand with 170141183420855150465331762880109871103 + sym::simd_fcos => ("cos", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fexp2 => ("exp2", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fexp => ("exp", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_flog10 => ("log10", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_flog2 => ("log2", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_flog => ("log", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)), + sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)), + sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)), + sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), + sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)), + _ => return_error!(InvalidMonomorphizationUnrecognized { span, name }), + }; let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str); let function = intrinsic::llvm::intrinsic(llvm_name, &bx.cx); let function: RValue<'gcc> = unsafe { std::mem::transmute(function) }; - let c = bx.call(fn_ty, None, function, &args.iter().map(|arg| arg.immediate()).collect::>(), None); + let c = bx.call( + fn_ty, + None, + function, + &args.iter().map(|arg| arg.immediate()).collect::>(), + None, + ); Ok(c) } @@ -518,7 +556,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, simd_neg: Int => neg, Float => fneg; } - #[cfg(feature="master")] + #[cfg(feature = "master")] if name == sym::simd_saturating_add || name == sym::simd_saturating_sub { let lhs = args[0].immediate(); let rhs = args[1].immediate(); @@ -536,18 +574,23 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, }); } }; - let builtin_name = - match (signed, is_add, in_len, elem_width) { - (true, true, 32, 8) => "__builtin_ia32_paddsb256", // TODO(antoyo): cast arguments to unsigned. - (false, true, 32, 8) => "__builtin_ia32_paddusb256", - (true, true, 16, 16) => "__builtin_ia32_paddsw256", - (false, true, 16, 16) => "__builtin_ia32_paddusw256", - (true, false, 16, 16) => "__builtin_ia32_psubsw256", - (false, false, 16, 16) => "__builtin_ia32_psubusw256", - (true, false, 32, 8) => "__builtin_ia32_psubsb256", - (false, false, 32, 8) => "__builtin_ia32_psubusb256", - _ => unimplemented!("signed: {}, is_add: {}, in_len: {}, elem_width: {}", signed, is_add, in_len, elem_width), - }; + let builtin_name = match (signed, is_add, in_len, elem_width) { + (true, true, 32, 8) => "__builtin_ia32_paddsb256", // TODO(antoyo): cast arguments to unsigned. + (false, true, 32, 8) => "__builtin_ia32_paddusb256", + (true, true, 16, 16) => "__builtin_ia32_paddsw256", + (false, true, 16, 16) => "__builtin_ia32_paddusw256", + (true, false, 16, 16) => "__builtin_ia32_psubsw256", + (false, false, 16, 16) => "__builtin_ia32_psubusw256", + (true, false, 32, 8) => "__builtin_ia32_psubsb256", + (false, false, 32, 8) => "__builtin_ia32_psubusb256", + _ => unimplemented!( + "signed: {}, is_add: {}, in_len: {}, elem_width: {}", + signed, + is_add, + in_len, + elem_width + ), + }; let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64); let func = bx.context.get_target_builtin_function(builtin_name); @@ -575,8 +618,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, // if overflow occurs, the result is the // mathematical result modulo 2^n: Ok(bx.$op(args[1].immediate(), r)) - } - else { + } else { Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op)) } } @@ -585,12 +627,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, // ordered arithmetic reductions take an accumulator let acc = args[1].immediate(); Ok(bx.$float_reduce(acc, args[0].immediate())) - } - else { + } else { Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op)) } } - _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }), + _ => return_error!(InvalidMonomorphizationUnsupportedElement { + span, + name, + in_ty, + elem_ty: in_elem, + ret_ty + }), }; } }; @@ -603,13 +650,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, add, 0.0 // TODO: Use this argument. ); - arith_red!( - simd_reduce_mul_unordered: BinaryOp::Mult, - vector_reduce_fmul_fast, - false, - mul, - 1.0 - ); + arith_red!(simd_reduce_mul_unordered: BinaryOp::Mult, vector_reduce_fmul_fast, false, mul, 1.0); macro_rules! minmax_red { ($name:ident: $reduction:ident) => { @@ -619,8 +660,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty } ); return match in_elem.kind() { - ty::Int(_) | ty::Uint(_) | ty::Float(_) => Ok(bx.$reduction(args[0].immediate())), - _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }), + ty::Int(_) | ty::Uint(_) | ty::Float(_) => { + Ok(bx.$reduction(args[0].immediate())) + } + _ => return_error!(InvalidMonomorphizationUnsupportedElement { + span, + name, + in_ty, + elem_ty: in_elem, + ret_ty + }), }; } }; @@ -641,7 +690,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, } else { match in_elem.kind() { ty::Int(_) | ty::Uint(_) => {} - _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }), + _ => return_error!(InvalidMonomorphizationUnsupportedElement { + span, + name, + in_ty, + elem_ty: in_elem, + ret_ty + }), } // boolean reductions operate on vectors of i1s: @@ -654,9 +709,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let r = bx.vector_reduce_op(input, $op); Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) }) } - _ => return_error!( - InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty } - ), + _ => return_error!(InvalidMonomorphizationUnsupportedElement { + span, + name, + in_ty, + elem_ty: in_elem, + ret_ty + }), }; } }; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index f73bbf3d22bd7..c1b3f34e5a6d4 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -132,7 +132,7 @@ fn build_fixed_size_array_di_node<'ll, 'tcx>( let (size, align) = cx.size_and_align_of(array_type); - let upper_bound = len.eval_usize(cx.tcx, ty::ParamEnv::reveal_all()) as c_longlong; + let upper_bound = len.eval_target_usize(cx.tcx, ty::ParamEnv::reveal_all()) as c_longlong; let subrange = unsafe { Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) }; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index dd89c4c59c14d..b0295481ca5a3 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -877,7 +877,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(), ty::Array(elem, len) if matches!(elem.kind(), ty::Uint(ty::UintTy::U8)) - && len.try_eval_usize(bx.tcx, ty::ParamEnv::reveal_all()) + && len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all()) == Some(expected_bytes) => { let place = PlaceRef::alloca(bx, args[0].layout); @@ -957,9 +957,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // version of this intrinsic. match args[2].layout.ty.kind() { ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => { - len.try_eval_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| { - span_bug!(span, "could not evaluate shuffle index array length") - }) + len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else( + || span_bug!(span, "could not evaluate shuffle index array length"), + ) } _ => return_error!(InvalidMonomorphization::SimdShuffle { span, @@ -1123,7 +1123,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } ty::Array(elem, len) if matches!(elem.kind(), ty::Uint(ty::UintTy::U8)) - && len.try_eval_usize(bx.tcx, ty::ParamEnv::reveal_all()) + && len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all()) == Some(expected_bytes) => { // Zero-extend iN to the array length: diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index de2727c8a5dc3..6e136db38954a 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -148,7 +148,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx.tcx().struct_lockstep_tails_erasing_lifetimes(source, target, bx.param_env()); match (source.kind(), target.kind()) { (&ty::Array(_, len), &ty::Slice(_)) => { - cx.const_usize(len.eval_usize(cx.tcx(), ty::ParamEnv::reveal_all())) + cx.const_usize(len.eval_target_usize(cx.tcx(), ty::ParamEnv::reveal_all())) } ( &ty::Dynamic(ref data_a, _, src_dyn_kind), diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index b0e007ce0097b..f2469fde3b657 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -181,16 +181,24 @@ fn push_debuginfo_type_name<'tcx>( push_debuginfo_type_name(tcx, inner_type, true, output, visited); match len.kind() { ty::ConstKind::Param(param) => write!(output, ",{}>", param.name).unwrap(), - _ => write!(output, ",{}>", len.eval_usize(tcx, ty::ParamEnv::reveal_all())) - .unwrap(), + _ => write!( + output, + ",{}>", + len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()) + ) + .unwrap(), } } else { output.push('['); push_debuginfo_type_name(tcx, inner_type, true, output, visited); match len.kind() { ty::ConstKind::Param(param) => write!(output, "; {}]", param.name).unwrap(), - _ => write!(output, "; {}]", len.eval_usize(tcx, ty::ParamEnv::reveal_all())) - .unwrap(), + _ => write!( + output, + "; {}]", + len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()) + ) + .unwrap(), } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 35948e50f48d0..7c8d23a3329c6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -100,8 +100,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - let count = - self.monomorphize(count).eval_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all()); + let count = self + .monomorphize(count) + .eval_target_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all()); bx.write_operand_repeatedly(cg_elem, count, dest); } @@ -492,7 +493,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if let Some(index) = place.as_local() { if let LocalRef::Operand(Some(op)) = self.locals[index] { if let ty::Array(_, n) = op.layout.ty.kind() { - let n = n.eval_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all()); + let n = n.eval_target_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all()); return bx.cx().const_usize(n); } } diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 01b2b4b5d9cd3..3bd586c81b0bd 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -107,7 +107,7 @@ pub(crate) fn try_destructure_mir_constant<'tcx>( // We go to `usize` as we cannot allocate anything bigger anyway. let (field_count, variant, down) = match val.ty().kind() { - ty::Array(_, len) => (len.eval_usize(tcx, param_env) as usize, None, op), + ty::Array(_, len) => (len.eval_target_usize(tcx, param_env) as usize, None, op), ty::Adt(def, _) if def.variants().is_empty() => { throw_ub!(Unreachable) } diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index fc8e0c67ae09a..9d00e338d453c 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -328,8 +328,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (&ty::Array(_, length), &ty::Slice(_)) => { let ptr = self.read_scalar(src)?; // u64 cast is from usize to u64, which is always good - let val = - Immediate::new_slice(ptr, length.eval_usize(*self.tcx, self.param_env), self); + let val = Immediate::new_slice( + ptr, + length.eval_target_usize(*self.tcx, self.param_env), + self, + ); self.write_immediate(val, dest) } (ty::Dynamic(data_a, ..), ty::Dynamic(data_b, ..)) => { diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 1a23b06d2e89c..faf741de60a16 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -473,7 +473,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // that this is merely a ZST and it is already eligible for promotion. // This may require an RFC? /* - ty::Array(_, len) if len.try_eval_usize(cx.tcx, cx.param_env) == Some(0) + ty::Array(_, len) if len.try_eval_target_usize(cx.tcx, cx.param_env) == Some(0) => true, */ _ => false, diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index fae6117f8f052..7009d3b38ae43 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -364,31 +364,33 @@ impl<'tcx> Validator<'_, 'tcx> { ProjectionElem::Index(local) => { let mut promotable = false; // Only accept if we can predict the index and are indexing an array. - let val = - if let TempState::Defined { location: loc, .. } = self.temps[local] { - let block = &self.body[loc.block]; - if loc.statement_index < block.statements.len() { - let statement = &block.statements[loc.statement_index]; - match &statement.kind { - StatementKind::Assign(box ( - _, - Rvalue::Use(Operand::Constant(c)), - )) => c.literal.try_eval_usize(self.tcx, self.param_env), - _ => None, - } - } else { - None + let val = if let TempState::Defined { location: loc, .. } = + self.temps[local] + { + let block = &self.body[loc.block]; + if loc.statement_index < block.statements.len() { + let statement = &block.statements[loc.statement_index]; + match &statement.kind { + StatementKind::Assign(box ( + _, + Rvalue::Use(Operand::Constant(c)), + )) => c.literal.try_eval_target_usize(self.tcx, self.param_env), + _ => None, } } else { None - }; + } + } else { + None + }; if let Some(idx) = val { // Determine the type of the thing we are indexing. let ty = place_base.ty(self.body, self.tcx).ty; match ty.kind() { ty::Array(_, len) => { // It's an array; determine its length. - if let Some(len) = len.try_eval_usize(self.tcx, self.param_env) + if let Some(len) = + len.try_eval_target_usize(self.tcx, self.param_env) { // If the index is in-bounds, go ahead. if idx < len { @@ -470,7 +472,7 @@ impl<'tcx> Validator<'_, 'tcx> { // mutably without consequences. However, only &mut [] // is allowed right now. if let ty::Array(_, len) = ty.kind() { - match len.try_eval_usize(self.tcx, self.param_env) { + match len.try_eval_target_usize(self.tcx, self.param_env) { Some(0) => {} _ => return Err(Unpromotable), } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 15a66ccc0f412..1d26ca70f38f3 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -901,7 +901,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { } let len = if let ty::Array(_ty, c) = e.kind() { - c.try_eval_usize(tcx, tcx.param_env(def.did())) + c.try_eval_target_usize(tcx, tcx.param_env(def.did())) } else { Some(fields.len() as u64) }; diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 12850c733e8a4..2f79071f6dc58 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1396,7 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { let tcx = self.tcx; let count = self.array_length_to_const(count); - if let Some(count) = count.try_eval_usize(tcx, self.param_env) { + if let Some(count) = count.try_eval_target_usize(tcx, self.param_env) { self.suggest_array_len(expr, count); } @@ -1463,7 +1463,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the length is 0, we don't create any elements, so we don't copy any. If the length is 1, we // don't copy that one element, we move it. Only check for Copy if the length is larger. - if count.try_eval_usize(tcx, self.param_env).map_or(true, |len| len > 1) { + if count.try_eval_target_usize(tcx, self.param_env).map_or(true, |len| len > 1) { let lang_item = self.tcx.require_lang_item(LangItem::Copy, None); let code = traits::ObligationCauseCode::RepeatElementCopy { is_const_fn }; self.require_type_meets(element_ty, element.span, code, lang_item); @@ -2602,7 +2602,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { len: ty::Const<'tcx>, ) { if let (Some(len), Ok(user_index)) = - (len.try_eval_usize(self.tcx, self.param_env), field.as_str().parse::()) + (len.try_eval_target_usize(self.tcx, self.param_env), field.as_str().parse::()) && let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) { let help = "instead of using tuple indexing, use array indexing"; diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 7af5260538568..29ed9a24ecfdf 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -647,7 +647,8 @@ fn check_must_not_suspend_ty<'tcx>( hir_id, SuspendCheckData { descr_pre, - plural_len: len.try_eval_usize(fcx.tcx, fcx.param_env).unwrap_or(0) as usize + plural_len: len.try_eval_target_usize(fcx.tcx, fcx.param_env).unwrap_or(0) + as usize + 1, ..data }, diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 3201035bdd8ba..e909511346dce 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2063,7 +2063,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { len: ty::Const<'tcx>, min_len: u64, ) -> (Option>, Ty<'tcx>) { - if let Some(len) = len.try_eval_usize(self.tcx, self.param_env) { + if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) { // Now we know the length... if slice.is_none() { // ...and since there is no variable-length pattern, diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 7a50b6aec87a6..f18c0aa377fb4 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2605,7 +2605,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { ty.tuple_fields().iter().find_map(|field| ty_find_init_error(cx, field, init)) } Array(ty, len) => { - if matches!(len.try_eval_usize(cx.tcx, cx.param_env), Some(v) if v > 0) { + if matches!(len.try_eval_target_usize(cx.tcx, cx.param_env), Some(v) if v > 0) { // Array length known at array non-empty -- recurse. ty_find_init_error(cx, *ty, init) } else { diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 88ea293444c17..3a92f5806c9ef 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -309,7 +309,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { None } } - ty::Array(ty, len) => match len.try_eval_usize(cx.tcx, cx.param_env) { + ty::Array(ty, len) => match len.try_eval_target_usize(cx.tcx, cx.param_env) { // If the array is empty we don't lint, to avoid false positives Some(0) | None => None, // If the array is definitely non-empty, we can do `#[must_use]` checking. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 6f42b69633c84..6378ca6e77ddf 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2344,9 +2344,13 @@ impl<'tcx> ConstantKind<'tcx> { } #[inline] - pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option { + pub fn try_eval_target_usize( + &self, + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> Option { match self { - Self::Ty(ct) => ct.try_eval_usize(tcx, param_env), + Self::Ty(ct) => ct.try_eval_target_usize(tcx, param_env), Self::Val(val, _) => val.try_to_machine_usize(tcx), Self::Unevaluated(uneval, _) => { match tcx.const_eval_resolve(param_env, *uneval, None) { diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 9f544de9f8720..97dc8a99f9b0e 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -97,7 +97,7 @@ impl<'tcx> PlaceTy<'tcx> { ty::Slice(..) => self.ty, ty::Array(inner, _) if !from_end => tcx.mk_array(*inner, (to - from) as u64), ty::Array(inner, size) if from_end => { - let size = size.eval_usize(tcx, param_env); + let size = size.eval_target_usize(tcx, param_env); let len = size - (from as u64) - (to as u64); tcx.mk_array(*inner, len) } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 65cbac3e8f1cd..3ad56e8f273df 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -175,7 +175,7 @@ impl<'tcx> Const<'tcx> { #[inline] /// Creates an interned usize constant. - pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { + pub fn from_target_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize)) } @@ -201,7 +201,11 @@ impl<'tcx> Const<'tcx> { } #[inline] - pub fn try_eval_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option { + pub fn try_eval_target_usize( + self, + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + ) -> Option { self.kind().eval(tcx, param_env).try_to_machine_usize(tcx) } @@ -229,8 +233,8 @@ impl<'tcx> Const<'tcx> { #[inline] /// Panics if the value cannot be evaluated or doesn't contain a valid `usize`. - pub fn eval_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 { - self.try_eval_usize(tcx, param_env) + pub fn eval_target_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 { + self.try_eval_target_usize(tcx, param_env) .unwrap_or_else(|| bug!("expected usize, got {:#?}", self)) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 02088fffeb6c3..e67c89c194ecb 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1787,7 +1787,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { - self.mk_ty(Array(ty, ty::Const::from_usize(self, n))) + self.mk_ty(Array(ty, ty::Const::from_target_usize(self, n))) } #[inline] diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 33f72729798dc..8d0c7bf2f478f 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -57,7 +57,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { match self { Self::False => Ok(false), Self::True => Ok(true), - Self::ConstIsZero(const_) => match const_.try_eval_usize(tcx, param_env) { + Self::ConstIsZero(const_) => match const_.try_eval_target_usize(tcx, param_env) { None | Some(0) => Ok(true), Some(1..) => Ok(false), }, diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 3b22da41a57b1..8b08ea9a58cbe 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -511,8 +511,8 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( // we however cannot end up with errors in `Relate` during both // `type_of` and `predicates_of`. This means that evaluating the // constants should not cause cycle errors here. - let sz_a = sz_a.try_eval_usize(tcx, relation.param_env()); - let sz_b = sz_b.try_eval_usize(tcx, relation.param_env()); + let sz_a = sz_a.try_eval_target_usize(tcx, relation.param_env()); + let sz_b = sz_b.try_eval_target_usize(tcx, relation.param_env()); match (sz_a, sz_b) { (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err( TypeError::FixedArraySize(expected_found(relation, sz_a_val, sz_b_val)), diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index abde81236e21a..c613b3627f2f6 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1879,7 +1879,7 @@ impl<'tcx> Ty<'tcx> { // The way we evaluate the `N` in `[T; N]` here only works since we use // `simd_size_and_type` post-monomorphization. It will probably start to ICE // if we use it in generic code. See the `simd-array-trait` ui test. - (f0_len.eval_usize(tcx, ParamEnv::empty()) as u64, *f0_elem_ty) + (f0_len.eval_target_usize(tcx, ParamEnv::empty()) as u64, *f0_elem_ty) } // Otherwise, the fields of this Adt are the SIMD components (and we assume they // all have the same type). diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index cd0e69328634b..fb0e9181b52ac 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -55,7 +55,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) } ExprKind::Repeat { value, count } => { - if Some(0) == count.try_eval_usize(this.tcx, this.param_env) { + if Some(0) == count.try_eval_target_usize(this.tcx, this.param_env) { this.build_zero_repeat(block, value, scope, source_info) } else { let value_operand = unpack!( diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index cbd494862a01f..fbe08a7bd243d 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -35,7 +35,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let tcx = self.tcx; let (min_length, exact_size) = if let Some(place_resolved) = place.try_to_place(self) { match place_resolved.ty(&self.local_decls, tcx).ty.kind() { - ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true), + ty::Array(_, length) => (length.eval_target_usize(tcx, self.param_env), true), _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false), } } else { diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index aba5429da435f..977c4b4ae6c0b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -922,8 +922,8 @@ impl<'tcx> SplitWildcard<'tcx> { // `cx.is_uninhabited()`). let all_ctors = match pcx.ty.kind() { ty::Bool => smallvec![make_range(0, 1)], - ty::Array(sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => { - let len = len.eval_usize(cx.tcx, cx.param_env) as usize; + ty::Array(sub_ty, len) if len.try_eval_target_usize(cx.tcx, cx.param_env).is_some() => { + let len = len.eval_target_usize(cx.tcx, cx.param_env) as usize; if len != 0 && cx.is_uninhabited(*sub_ty) { smallvec![] } else { @@ -1406,7 +1406,9 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { } PatKind::Array { prefix, slice, suffix } | PatKind::Slice { prefix, slice, suffix } => { let array_len = match pat.ty.kind() { - ty::Array(_, length) => Some(length.eval_usize(cx.tcx, cx.param_env) as usize), + ty::Array(_, length) => { + Some(length.eval_target_usize(cx.tcx, cx.param_env) as usize) + } ty::Slice(_) => None, _ => span_bug!(pat.span, "bad ty {:?} for slice pattern", pat.ty), }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 3a6ef87c9c662..47ca0a87fcc28 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -416,7 +416,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ty::Slice(..) => PatKind::Slice { prefix, slice, suffix }, // Fixed-length array, `[T; len]`. ty::Array(_, len) => { - let len = len.eval_usize(self.tcx, self.param_env); + let len = len.eval_target_usize(self.tcx, self.param_env); assert!(len >= prefix.len() as u64 + suffix.len() as u64); PatKind::Array { prefix, slice, suffix } } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 7836ae2e7b76f..bd12087629c99 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -890,7 +890,7 @@ where } ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind), ty::Array(ety, size) => { - let size = size.try_eval_usize(self.tcx(), self.elaborator.param_env()); + let size = size.try_eval_target_usize(self.tcx(), self.elaborator.param_env()); self.open_drop_for_array(*ety, size) } ty::Slice(ety) => self.open_drop_for_array(*ety, None), diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 115c8afcce0cf..6d30276aeabe0 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -490,7 +490,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { }; let base_ty = base_place.ty(self.builder.body, self.builder.tcx).ty; let len: u64 = match base_ty.kind() { - ty::Array(_, size) => size.eval_usize(self.builder.tcx, self.builder.param_env), + ty::Array(_, size) => { + size.eval_target_usize(self.builder.tcx, self.builder.param_env) + } _ => bug!("from_end: false slice pattern of non-array type"), }; for offset in from..to { diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 47f9d35a4f7ec..35c6037fa2923 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1845,7 +1845,7 @@ fn check_must_not_suspend_ty<'tcx>( param_env, SuspendCheckData { descr_pre, - plural_len: len.try_eval_usize(tcx, param_env).unwrap_or(0) as usize + 1, + plural_len: len.try_eval_target_usize(tcx, param_env).unwrap_or(0) as usize + 1, ..data }, ) diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 89f8de235835a..194c41c6ba1c0 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -143,7 +143,7 @@ impl EnumSizeOpt { let tmp_ty = tcx.mk_ty(ty::Array( tcx.types.usize, - Const::from_usize(tcx, num_variants as u64), + Const::from_target_usize(tcx, num_variants as u64), )); let size_array_local = local_decls.push(LocalDecl::new(tmp_ty, span)); diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 8402499b296d7..32dd8f25b4420 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -112,7 +112,7 @@ impl<'tcx> TypeVisitor> for Search<'tcx> { return ControlFlow::Continue(()); } ty::Array(_, n) - if { n.try_eval_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0) } => + if { n.try_eval_target_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0) } => { // rust-lang/rust#62336: ignore type of contents // for empty array. diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 30e20ba6f5868..295b65c2cc925 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -284,8 +284,9 @@ pub(crate) mod rustc { } ty::Array(ty, len) => { - let len = - len.try_eval_usize(tcx, ParamEnv::reveal_all()).ok_or(Err::Unspecified)?; + let len = len + .try_eval_target_usize(tcx, ParamEnv::reveal_all()) + .ok_or(Err::Unspecified)?; let elt = Tree::from_ty(*ty, tcx)?; Ok(std::iter::repeat(elt) .take(len as usize) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 137289198786e..d9efcaaebd5bc 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -209,7 +209,8 @@ fn layout_of_uncached<'tcx>( } } - let count = count.try_eval_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?; + let count = + count.try_eval_target_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?; let element = cx.layout_of(element)?; let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?; diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs index eebfb753a0c5d..c384172fbde83 100644 --- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs @@ -109,7 +109,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { if let Some(range) = higher::Range::hir(index) { // Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..] if let ty::Array(_, s) = ty.kind() { - let size: u128 = if let Some(size) = s.try_eval_usize(cx.tcx, cx.param_env) { + let size: u128 = if let Some(size) = s.try_eval_target_usize(cx.tcx, cx.param_env) { size.into() } else { return; diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index b1f2941622abb..151c7f1d5d254 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -68,7 +68,7 @@ fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { // IntoIterator is currently only implemented for array sizes <= 32 in rustc match ty.kind() { ty::Array(_, n) => n - .try_eval_usize(cx.tcx, cx.param_env) + .try_eval_target_usize(cx.tcx, cx.param_env) .map_or(false, |val| (0..=32).contains(&val)), _ => false, } diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index 25a1a5842f77b..5c317c2a5bbb6 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -211,7 +211,7 @@ fn is_end_eq_array_len<'tcx>( if let ExprKind::Lit(ref lit) = end.kind; if let ast::LitKind::Int(end_int, _) = lit.node; if let ty::Array(_, arr_len_const) = indexed_ty.kind(); - if let Some(arr_len) = arr_len_const.try_eval_usize(cx.tcx, cx.param_env); + if let Some(arr_len) = arr_len_const.try_eval_target_usize(cx.tcx, cx.param_env); then { return match limits { ast::RangeLimits::Closed => end_int + 1 >= arr_len.into(), diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs index ae6b165fdc366..d50346c166ae0 100644 --- a/src/tools/clippy/clippy_lints/src/methods/utils.rs +++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs @@ -22,7 +22,7 @@ pub(super) fn derefs_to_slice<'tcx>( ty::Slice(_) => true, ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()), ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::Vec), - ty::Array(_, size) => size.try_eval_usize(cx.tcx, cx.param_env).is_some(), + ty::Array(_, size) => size.try_eval_target_usize(cx.tcx, cx.param_env).is_some(), ty::Ref(_, inner, _) => may_slice(cx, *inner), _ => false, } diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs index 5f7aac21e6eb0..3cc765108d7cc 100644 --- a/src/tools/clippy/clippy_lints/src/mut_key.rs +++ b/src/tools/clippy/clippy_lints/src/mut_key.rs @@ -166,7 +166,7 @@ impl MutableKeyType { Ref(_, inner_ty, mutbl) => mutbl == hir::Mutability::Mut || self.is_interior_mutable_type(cx, inner_ty), Slice(inner_ty) => self.is_interior_mutable_type(cx, inner_ty), Array(inner_ty, size) => { - size.try_eval_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0) + size.try_eval_target_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0) && self.is_interior_mutable_type(cx, inner_ty) }, Tuple(fields) => fields.iter().any(|ty| self.is_interior_mutable_type(cx, ty)), diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index de0c5d56e4156..1382c1a40da24 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -62,7 +62,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_ // Then check if that that array zero-sized let length = Const::from_anon_const(cx.tcx, length.def_id); - let length = length.try_eval_usize(cx.tcx, cx.param_env); + let length = length.try_eval_target_usize(cx.tcx, cx.param_env); if let Some(length) = length; then { length == 0 diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index a67bd8d46006b..9d812fbdcc37e 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -335,7 +335,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { ExprKind::Tup(tup) => self.multi(tup).map(Constant::Tuple), ExprKind::Repeat(value, _) => { let n = match self.typeck_results.expr_ty(e).kind() { - ty::Array(_, n) => n.try_eval_usize(self.lcx.tcx, self.lcx.param_env)?, + ty::Array(_, n) => n.try_eval_target_usize(self.lcx.tcx, self.lcx.param_env)?, _ => span_bug!(e.span, "typeck error"), }; self.expr(value).map(|v| Constant::Repeat(Box::new(v), n)) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index c785d89e28012..0d763a2c5cf6b 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -949,7 +949,7 @@ pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 { (Ok(size), _) => size, (Err(_), ty::Tuple(list)) => list.as_substs().types().map(|t| approx_ty_size(cx, t)).sum(), (Err(_), ty::Array(t, n)) => { - n.try_eval_usize(cx.tcx, cx.param_env).unwrap_or_default() * approx_ty_size(cx, *t) + n.try_eval_target_usize(cx.tcx, cx.param_env).unwrap_or_default() * approx_ty_size(cx, *t) }, (Err(_), ty::Adt(def, subst)) if def.is_struct() => def .variants() diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index c1b949b1f7993..f24ddb887b95a 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -469,7 +469,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ty::Array(_, index_len) = index.layout.ty.kind() else { span_bug!(this.cur_span(), "simd_shuffle index argument has non-array type {}", index.layout.ty) }; - let index_len = index_len.eval_usize(*this.tcx, this.param_env()); + let index_len = index_len.eval_target_usize(*this.tcx, this.param_env()); assert_eq!(left_len, right_len); assert_eq!(index_len, dest_len); From 0e185c2df1ba8cc747744db3d9cdd7c81a7fefe0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 14 Feb 2023 10:51:15 +0000 Subject: [PATCH 18/21] Avoid using a dead email address as the main email address --- .mailmap | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.mailmap b/.mailmap index b814767786f2a..726d4c3d1d262 100644 --- a/.mailmap +++ b/.mailmap @@ -419,18 +419,18 @@ Nixon Enraght-Moony NODA Kai oliver <16816606+o752d@users.noreply.github.com> Oliver Middleton -Oliver Scherer -Oliver Scherer -Oliver Scherer -Oliver Scherer -Oliver Scherer -Oliver Scherer -Oliver Scherer -Oliver Scherer -Oliver Scherer -Oliver Scherer -Oliver Scherer -Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer Ömer Sinan Ağacan Ophir LOJKINE Ožbolt Menegatti gareins From 9e2947a62114e095c589854ae60b6c8df37b5c7a Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Tue, 14 Feb 2023 09:53:12 +0000 Subject: [PATCH 19/21] Ord entails its supertraits --- compiler/rustc_type_ir/src/lib.rs | 50 +++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 29d261fda8d9c..f27bcb9ea6b73 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -39,35 +39,35 @@ pub use ty_info::*; pub trait HashStableContext {} pub trait Interner: Sized { - type AdtDef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type SubstsRef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type DefId: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; + type AdtDef: Clone + Debug + Hash + Ord; + type SubstsRef: Clone + Debug + Hash + Ord; + type DefId: Clone + Debug + Hash + Ord; type Binder; - type Ty: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type Const: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type Region: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; + type Ty: Clone + Debug + Hash + Ord; + type Const: Clone + Debug + Hash + Ord; + type Region: Clone + Debug + Hash + Ord; type Predicate; - type TypeAndMut: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type Mutability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type Movability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type PolyFnSig: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type ListBinderExistentialPredicate: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type BinderListTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type ListTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type AliasTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type ParamTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type BoundTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type PlaceholderType: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type InferTy: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type ErrorGuaranteed: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; + type TypeAndMut: Clone + Debug + Hash + Ord; + type Mutability: Clone + Debug + Hash + Ord; + type Movability: Clone + Debug + Hash + Ord; + type PolyFnSig: Clone + Debug + Hash + Ord; + type ListBinderExistentialPredicate: Clone + Debug + Hash + Ord; + type BinderListTy: Clone + Debug + Hash + Ord; + type ListTy: Clone + Debug + Hash + Ord; + type AliasTy: Clone + Debug + Hash + Ord; + type ParamTy: Clone + Debug + Hash + Ord; + type BoundTy: Clone + Debug + Hash + Ord; + type PlaceholderType: Clone + Debug + Hash + Ord; + type InferTy: Clone + Debug + Hash + Ord; + type ErrorGuaranteed: Clone + Debug + Hash + Ord; type PredicateKind: Clone + Debug + Hash + PartialEq + Eq; - type AllocId: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; + type AllocId: Clone + Debug + Hash + Ord; - type EarlyBoundRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type BoundRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type FreeRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type RegionVid: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type PlaceholderRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; + type EarlyBoundRegion: Clone + Debug + Hash + Ord; + type BoundRegion: Clone + Debug + Hash + Ord; + type FreeRegion: Clone + Debug + Hash + Ord; + type RegionVid: Clone + Debug + Hash + Ord; + type PlaceholderRegion: Clone + Debug + Hash + Ord; } pub trait InternAs { From c8dae10f14122555bfc1625b037b92eb104e67ad Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 6 Feb 2023 17:11:43 -0300 Subject: [PATCH 20/21] Check for overflow in evaluate_canonical_goal --- .../rustc_trait_selection/src/solve/mod.rs | 23 +++------- .../src/solve/search_graph/mod.rs | 43 ++++++++++++++++--- .../src/solve/search_graph/overflow.rs | 4 +- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 358a2bcc7b9eb..d444ca69df101 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -211,27 +211,16 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { search_graph: &'a mut search_graph::SearchGraph<'tcx>, canonical_goal: CanonicalGoal<'tcx>, ) -> QueryResult<'tcx> { - match search_graph.try_push_stack(tcx, canonical_goal) { - Ok(()) => {} - // Our goal is already on the stack, eager return. - Err(response) => return response, - } - - // We may have to repeatedly recompute the goal in case of coinductive cycles, - // check out the `cache` module for more information. + // Deal with overflow, caching, and coinduction. // - // FIXME: Similar to `evaluate_all`, this has to check for overflow. - loop { + // The actual solver logic happens in `ecx.compute_goal`. + search_graph.with_new_goal(tcx, canonical_goal, |search_graph| { let (ref infcx, goal, var_values) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical_goal); let mut ecx = EvalCtxt { infcx, var_values, search_graph, in_projection_eq_hack: false }; - let result = ecx.compute_goal(goal); - - if search_graph.try_finalize_goal(tcx, canonical_goal, result) { - return result; - } - } + ecx.compute_goal(goal) + }) } fn make_canonical_response(&self, certainty: Certainty) -> QueryResult<'tcx> { @@ -487,7 +476,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ) -> Result { let mut new_goals = Vec::new(); self.repeat_while_none( - |_| Certainty::Maybe(MaybeCause::Overflow), + |_| Ok(Certainty::Maybe(MaybeCause::Overflow)), |this| { let mut has_changed = Err(Certainty::Yes); for goal in goals.drain(..) { diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 438bcd9a7d689..9b398ef0e6232 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -3,6 +3,7 @@ pub(crate) mod overflow; use self::cache::ProvisionalEntry; use super::{CanonicalGoal, Certainty, MaybeCause, QueryResult}; +use crate::solve::search_graph::overflow::OverflowHandler; use cache::ProvisionalCache; use overflow::OverflowData; use rustc_index::vec::IndexVec; @@ -13,7 +14,7 @@ rustc_index::newtype_index! { pub struct StackDepth {} } -struct StackElem<'tcx> { +pub(crate) struct StackElem<'tcx> { goal: CanonicalGoal<'tcx>, has_been_used: bool, } @@ -127,7 +128,8 @@ impl<'tcx> SearchGraph<'tcx> { actual_goal: CanonicalGoal<'tcx>, response: QueryResult<'tcx>, ) -> bool { - let StackElem { goal, has_been_used } = self.stack.pop().unwrap(); + let stack_elem = self.stack.pop().unwrap(); + let StackElem { goal, has_been_used } = stack_elem; assert_eq!(goal, actual_goal); let cache = &mut self.provisional_cache; @@ -156,7 +158,7 @@ impl<'tcx> SearchGraph<'tcx> { self.stack.push(StackElem { goal, has_been_used: false }); false } else { - self.try_move_finished_goal_to_global_cache(tcx, &goal); + self.try_move_finished_goal_to_global_cache(tcx, stack_elem); true } } @@ -164,10 +166,11 @@ impl<'tcx> SearchGraph<'tcx> { pub(super) fn try_move_finished_goal_to_global_cache( &mut self, tcx: TyCtxt<'tcx>, - goal: &CanonicalGoal<'tcx>, + stack_elem: StackElem<'tcx>, ) { + let StackElem { goal, .. } = stack_elem; let cache = &mut self.provisional_cache; - let provisional_entry_index = *cache.lookup_table.get(goal).unwrap(); + let provisional_entry_index = *cache.lookup_table.get(&goal).unwrap(); let provisional_entry = &mut cache.entries[provisional_entry_index]; let depth = provisional_entry.depth; @@ -193,4 +196,34 @@ impl<'tcx> SearchGraph<'tcx> { } } } + + pub(super) fn with_new_goal( + &mut self, + tcx: TyCtxt<'tcx>, + canonical_goal: CanonicalGoal<'tcx>, + mut loop_body: impl FnMut(&mut Self) -> QueryResult<'tcx>, + ) -> QueryResult<'tcx> { + match self.try_push_stack(tcx, canonical_goal) { + Ok(()) => {} + // Our goal is already on the stack, eager return. + Err(response) => return response, + } + + self.repeat_while_none( + |this| { + let result = this.deal_with_overflow(tcx, canonical_goal); + let stack_elem = this.stack.pop().unwrap(); + this.try_move_finished_goal_to_global_cache(tcx, stack_elem); + result + }, + |this| { + let result = loop_body(this); + if this.try_finalize_goal(tcx, canonical_goal, result) { + Some(result) + } else { + None + } + }, + ) + } } diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs index 0d6863b1e813d..ea62152789e48 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs @@ -55,7 +55,7 @@ pub(crate) trait OverflowHandler<'tcx> { fn repeat_while_none( &mut self, - on_overflow: impl FnOnce(&mut Self) -> T, + on_overflow: impl FnOnce(&mut Self) -> Result, mut loop_body: impl FnMut(&mut Self) -> Option>, ) -> Result { let start_depth = self.search_graph().overflow_data.additional_depth; @@ -70,7 +70,7 @@ pub(crate) trait OverflowHandler<'tcx> { } self.search_graph().overflow_data.additional_depth = start_depth; self.search_graph().overflow_data.deal_with_overflow(); - Ok(on_overflow(self)) + on_overflow(self) } } From 26136c6224345743952642600f7bafe78df46449 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 Feb 2023 10:01:30 -0300 Subject: [PATCH 21/21] Reduce visibility of some items --- compiler/rustc_trait_selection/src/solve/mod.rs | 2 +- .../src/solve/search_graph/mod.rs | 14 +++++++------- .../src/solve/search_graph/overflow.rs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index d444ca69df101..32fcd751b468d 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -31,7 +31,7 @@ use rustc_middle::ty::{ }; use rustc_span::DUMMY_SP; -use crate::solve::search_graph::overflow::OverflowHandler; +use crate::solve::search_graph::OverflowHandler; use crate::traits::ObligationCause; mod assembly; diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 9b398ef0e6232..e9945cde5df25 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -1,9 +1,9 @@ mod cache; -pub(crate) mod overflow; +mod overflow; use self::cache::ProvisionalEntry; use super::{CanonicalGoal, Certainty, MaybeCause, QueryResult}; -use crate::solve::search_graph::overflow::OverflowHandler; +pub(super) use crate::solve::search_graph::overflow::OverflowHandler; use cache::ProvisionalCache; use overflow::OverflowData; use rustc_index::vec::IndexVec; @@ -14,12 +14,12 @@ rustc_index::newtype_index! { pub struct StackDepth {} } -pub(crate) struct StackElem<'tcx> { +struct StackElem<'tcx> { goal: CanonicalGoal<'tcx>, has_been_used: bool, } -pub(crate) struct SearchGraph<'tcx> { +pub(super) struct SearchGraph<'tcx> { /// The stack of goals currently being computed. /// /// An element is *deeper* in the stack if its index is *lower*. @@ -47,7 +47,7 @@ impl<'tcx> SearchGraph<'tcx> { /// /// This correctly updates the provisional cache if there is a cycle. #[instrument(level = "debug", skip(self, tcx), ret)] - pub(super) fn try_push_stack( + fn try_push_stack( &mut self, tcx: TyCtxt<'tcx>, goal: CanonicalGoal<'tcx>, @@ -122,7 +122,7 @@ impl<'tcx> SearchGraph<'tcx> { /// /// FIXME: Refer to the rustc-dev-guide entry once it exists. #[instrument(level = "debug", skip(self, tcx, actual_goal), ret)] - pub(super) fn try_finalize_goal( + fn try_finalize_goal( &mut self, tcx: TyCtxt<'tcx>, actual_goal: CanonicalGoal<'tcx>, @@ -163,7 +163,7 @@ impl<'tcx> SearchGraph<'tcx> { } } - pub(super) fn try_move_finished_goal_to_global_cache( + fn try_move_finished_goal_to_global_cache( &mut self, tcx: TyCtxt<'tcx>, stack_elem: StackElem<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs index ea62152789e48..56409b0602be9 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs @@ -50,7 +50,7 @@ impl OverflowData { } } -pub(crate) trait OverflowHandler<'tcx> { +pub(in crate::solve) trait OverflowHandler<'tcx> { fn search_graph(&mut self) -> &mut SearchGraph<'tcx>; fn repeat_while_none(