From 85a9c741588aaf296ce94f480e342c2bf5c131ba Mon Sep 17 00:00:00 2001 From: AngelicosPhosphoros Date: Sun, 17 Jul 2022 23:33:29 +0300 Subject: [PATCH 01/23] Add tests that check `Vec::retain` predicate execution order. --- library/alloc/tests/vec.rs | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 5520f6ebf1904..b17f7a8eebc56 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -292,6 +292,22 @@ fn test_retain() { assert_eq!(vec, [2, 4]); } +#[test] +fn test_retain_predicate_order() { + for to_keep in [true, false] { + let mut number_of_executions = 0; + let mut vec = vec![1, 2, 3, 4]; + let mut next_expected = 1; + vec.retain(|&x| { + assert_eq!(next_expected, x); + next_expected += 1; + number_of_executions += 1; + to_keep + }); + assert_eq!(number_of_executions, 4); + } +} + #[test] fn test_retain_pred_panic_with_hole() { let v = (0..5).map(Rc::new).collect::>(); @@ -353,6 +369,35 @@ fn test_retain_drop_panic() { assert!(v.iter().all(|r| Rc::strong_count(r) == 1)); } +#[test] +fn test_retain_maybeuninits() { + // This test aimed to be run under miri. + use core::mem::MaybeUninit; + let mut vec: Vec<_> = [1i32, 2, 3, 4].map(|v| MaybeUninit::new(vec![v])).into(); + vec.retain(|x| { + // SAFETY: Retain must visit every element of Vec in original order and exactly once. + // Our values is initialized at creation of Vec. + let v = unsafe { x.assume_init_ref()[0] }; + if v & 1 == 0 { + return true; + } + // SAFETY: Value is initialized. + // Value wouldn't be dropped by `Vec::retain` + // because `MaybeUninit` doesn't drop content. + drop(unsafe { x.assume_init_read() }); + false + }); + let vec: Vec = vec + .into_iter() + .map(|x| unsafe { + // SAFETY: All values dropped in retain predicate must be removed by `Vec::retain`. + // Remaining values are initialized. + x.assume_init()[0] + }) + .collect(); + assert_eq!(vec, [2, 4]); +} + #[test] fn test_dedup() { fn case(a: Vec, b: Vec) { From c6558c0bc71024b8aca1db317c15cdf701d917d8 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 29 Jul 2022 20:04:28 +0400 Subject: [PATCH 02/23] Recover keywords in bounds For example, this fixes a error for `impl fn()` (notice the capitalization) --- compiler/rustc_parse/src/parser/ty.rs | 8 +++++++- .../ui/rfc-2632-const-trait-impl/without-tilde.rs | 3 ++- .../rfc-2632-const-trait-impl/without-tilde.stderr | 12 +++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 31b40a83e6052..b76ba8ff2d98c 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -640,7 +640,13 @@ impl<'a> Parser<'a> { let mut bounds = Vec::new(); let mut negative_bounds = Vec::new(); - while self.can_begin_bound() || self.token.is_keyword(kw::Dyn) { + while self.can_begin_bound() + // Continue even if we find a keyword. + // This is necessary for error recover on, for example, `impl fn()`. + // + // The only keyword that can go after generic bounds is `where`, so stop if it's it. + || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where)) + { if self.token.is_keyword(kw::Dyn) { // Account for `&dyn Trait + dyn Other`. self.struct_span_err(self.token.span, "invalid `dyn` keyword") diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs index e8b261545499f..e0d3e0b497b3f 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs @@ -3,4 +3,5 @@ #![feature(const_trait_impl)] struct S; -//~^ ERROR expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path +//~^ ERROR expected identifier, found keyword `const` +//~| ERROR expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr` diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr index b6b77ac4a2fb6..243f0979509bf 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr @@ -1,8 +1,14 @@ -error: expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path, found keyword `const` +error: expected identifier, found keyword `const` --> $DIR/without-tilde.rs:5:13 | LL | struct S; - | ^^^^^ expected one of 10 possible tokens + | ^^^^^ expected identifier, found keyword -error: aborting due to previous error +error: expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr` + --> $DIR/without-tilde.rs:5:19 + | +LL | struct S; + | ^^ expected one of 7 possible tokens + +error: aborting due to 2 previous errors From 798016c2df3a15da739e8c6d0968ba0f7b54e303 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 29 Jul 2022 21:59:08 +0400 Subject: [PATCH 03/23] add a silly test for keywords in trait bounds recovery --- src/test/ui/parser/kw-in-trait-bounds.rs | 47 +++++ src/test/ui/parser/kw-in-trait-bounds.stderr | 171 +++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 src/test/ui/parser/kw-in-trait-bounds.rs create mode 100644 src/test/ui/parser/kw-in-trait-bounds.stderr diff --git a/src/test/ui/parser/kw-in-trait-bounds.rs b/src/test/ui/parser/kw-in-trait-bounds.rs new file mode 100644 index 0000000000000..fa037e5937dca --- /dev/null +++ b/src/test/ui/parser/kw-in-trait-bounds.rs @@ -0,0 +1,47 @@ +// edition:2018 + +fn _f(_: impl fn(), _: &dyn fn()) +//~^ ERROR expected identifier, found keyword `fn` +//~| ERROR expected identifier, found keyword `fn` +//~| ERROR expected identifier, found keyword `fn` +//~| ERROR cannot find trait `r#fn` in this scope +//~| ERROR cannot find trait `r#fn` in this scope +//~| ERROR cannot find trait `r#fn` in this scope +//~| HELP a trait with a similar name exists +//~| HELP a trait with a similar name exists +//~| HELP a trait with a similar name exists +//~| HELP escape `fn` to use it as an identifier +//~| HELP escape `fn` to use it as an identifier +//~| HELP escape `fn` to use it as an identifier +where +G: fn(), + //~^ ERROR expected identifier, found keyword `fn` + //~| ERROR cannot find trait `r#fn` in this scope + //~| HELP a trait with a similar name exists + //~| HELP escape `fn` to use it as an identifier +{} + +fn _g(_: impl struct, _: &dyn struct) +//~^ ERROR expected identifier, found keyword `struct` +//~| ERROR expected identifier, found keyword `struct` +//~| ERROR expected identifier, found keyword `struct` +//~| ERROR cannot find trait `r#struct` in this scope +//~| ERROR cannot find trait `r#struct` in this scope +//~| ERROR cannot find trait `r#struct` in this scope +//~| HELP a trait with a similar name exists +//~| HELP a trait with a similar name exists +//~| HELP a trait with a similar name exists +//~| HELP escape `struct` to use it as an identifier +//~| HELP escape `struct` to use it as an identifier +//~| HELP escape `struct` to use it as an identifier +where + B: struct, + //~^ ERROR expected identifier, found keyword `struct` + //~| ERROR cannot find trait `r#struct` in this scope + //~| HELP a trait with a similar name exists + //~| HELP escape `struct` to use it as an identifier +{} + +trait Struct {} + +fn main() {} diff --git a/src/test/ui/parser/kw-in-trait-bounds.stderr b/src/test/ui/parser/kw-in-trait-bounds.stderr new file mode 100644 index 0000000000000..28196c7ce2de8 --- /dev/null +++ b/src/test/ui/parser/kw-in-trait-bounds.stderr @@ -0,0 +1,171 @@ +error: expected identifier, found keyword `fn` + --> $DIR/kw-in-trait-bounds.rs:3:10 + | +LL | fn _f(_: impl fn(), _: &dyn fn()) + | ^^ expected identifier, found keyword + | +help: escape `fn` to use it as an identifier + | +LL | fn _f(_: impl fn(), _: &dyn fn()) + | ++ + +error: expected identifier, found keyword `fn` + --> $DIR/kw-in-trait-bounds.rs:3:27 + | +LL | fn _f(_: impl fn(), _: &dyn fn()) + | ^^ expected identifier, found keyword + | +help: escape `fn` to use it as an identifier + | +LL | fn _f(_: impl r#fn(), _: &dyn fn()) + | ++ + +error: expected identifier, found keyword `fn` + --> $DIR/kw-in-trait-bounds.rs:3:41 + | +LL | fn _f(_: impl fn(), _: &dyn fn()) + | ^^ expected identifier, found keyword + | +help: escape `fn` to use it as an identifier + | +LL | fn _f(_: impl fn(), _: &dyn r#fn()) + | ++ + +error: expected identifier, found keyword `fn` + --> $DIR/kw-in-trait-bounds.rs:17:4 + | +LL | G: fn(), + | ^^ expected identifier, found keyword + | +help: escape `fn` to use it as an identifier + | +LL | G: r#fn(), + | ++ + +error: expected identifier, found keyword `struct` + --> $DIR/kw-in-trait-bounds.rs:24:10 + | +LL | fn _g(_: impl struct, _: &dyn struct) + | ^^^^^^ expected identifier, found keyword + | +help: escape `struct` to use it as an identifier + | +LL | fn _g(_: impl struct, _: &dyn struct) + | ++ + +error: expected identifier, found keyword `struct` + --> $DIR/kw-in-trait-bounds.rs:24:29 + | +LL | fn _g(_: impl struct, _: &dyn struct) + | ^^^^^^ expected identifier, found keyword + | +help: escape `struct` to use it as an identifier + | +LL | fn _g(_: impl r#struct, _: &dyn struct) + | ++ + +error: expected identifier, found keyword `struct` + --> $DIR/kw-in-trait-bounds.rs:24:45 + | +LL | fn _g(_: impl struct, _: &dyn struct) + | ^^^^^^ expected identifier, found keyword + | +help: escape `struct` to use it as an identifier + | +LL | fn _g(_: impl struct, _: &dyn r#struct) + | ++ + +error: expected identifier, found keyword `struct` + --> $DIR/kw-in-trait-bounds.rs:38:8 + | +LL | B: struct, + | ^^^^^^ expected identifier, found keyword + | +help: escape `struct` to use it as an identifier + | +LL | B: r#struct, + | ++ + +error[E0405]: cannot find trait `r#fn` in this scope + --> $DIR/kw-in-trait-bounds.rs:3:10 + | +LL | fn _f(_: impl fn(), _: &dyn fn()) + | ^^ help: a trait with a similar name exists (notice the capitalization): `Fn` + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait Fn: FnMut { + | ------------------------------- similarly named trait `Fn` defined here + +error[E0405]: cannot find trait `r#fn` in this scope + --> $DIR/kw-in-trait-bounds.rs:17:4 + | +LL | G: fn(), + | ^^ help: a trait with a similar name exists (notice the capitalization): `Fn` + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait Fn: FnMut { + | ------------------------------- similarly named trait `Fn` defined here + +error[E0405]: cannot find trait `r#fn` in this scope + --> $DIR/kw-in-trait-bounds.rs:3:27 + | +LL | fn _f(_: impl fn(), _: &dyn fn()) + | ^^ help: a trait with a similar name exists (notice the capitalization): `Fn` + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait Fn: FnMut { + | ------------------------------- similarly named trait `Fn` defined here + +error[E0405]: cannot find trait `r#fn` in this scope + --> $DIR/kw-in-trait-bounds.rs:3:41 + | +LL | fn _f(_: impl fn(), _: &dyn fn()) + | ^^ help: a trait with a similar name exists (notice the capitalization): `Fn` + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait Fn: FnMut { + | ------------------------------- similarly named trait `Fn` defined here + +error[E0405]: cannot find trait `r#struct` in this scope + --> $DIR/kw-in-trait-bounds.rs:24:10 + | +LL | fn _g(_: impl struct, _: &dyn struct) + | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` +... +LL | trait Struct {} + | ------------ similarly named trait `Struct` defined here + +error[E0405]: cannot find trait `r#struct` in this scope + --> $DIR/kw-in-trait-bounds.rs:38:8 + | +LL | B: struct, + | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` +... +LL | trait Struct {} + | ------------ similarly named trait `Struct` defined here + +error[E0405]: cannot find trait `r#struct` in this scope + --> $DIR/kw-in-trait-bounds.rs:24:29 + | +LL | fn _g(_: impl struct, _: &dyn struct) + | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` +... +LL | trait Struct {} + | ------------ similarly named trait `Struct` defined here + +error[E0405]: cannot find trait `r#struct` in this scope + --> $DIR/kw-in-trait-bounds.rs:24:45 + | +LL | fn _g(_: impl struct, _: &dyn struct) + | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` +... +LL | trait Struct {} + | ------------ similarly named trait `Struct` defined here + +error: aborting due to 16 previous errors + +For more information about this error, try `rustc --explain E0405`. From c198a20f7c2cb96842a705e770ea0b9dc35b9be0 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Fri, 19 Aug 2022 17:08:59 +0300 Subject: [PATCH 04/23] Catch overflow early --- .../src/traits/project.rs | 12 ++++++++ src/test/ui/issues/issue-23122-2.stderr | 7 +---- src/test/ui/recursion/issue-83150.stderr | 6 ++-- src/test/ui/recursion/issue-95134.rs | 28 +++++++++++++++++++ src/test/ui/recursion/issue-95134.stderr | 7 +++++ 5 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/recursion/issue-95134.rs create mode 100644 src/test/ui/recursion/issue-95134.stderr diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 715b97492683b..aeaccffd5f5f7 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -554,6 +554,18 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { .flatten() .unwrap_or_else(|| ty::Term::Ty(ty.super_fold_with(self))) }; + // For cases like #95134 we would like to catch overflows early + // otherwise they slip away away and cause ICE. + let recursion_limit = self.tcx().recursion_limit(); + if !recursion_limit.value_within_limit(self.depth) { + let obligation = Obligation::with_depth( + self.cause.clone(), + recursion_limit.0, + self.param_env, + ty, + ); + self.selcx.infcx().report_overflow_error(&obligation, true); + } debug!( ?self.depth, ?ty, diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr index 3d8e7b969184e..f6cda3de5c763 100644 --- a/src/test/ui/issues/issue-23122-2.stderr +++ b/src/test/ui/issues/issue-23122-2.stderr @@ -1,15 +1,10 @@ -error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized` +error[E0275]: overflow evaluating the requirement `::Next` --> $DIR/issue-23122-2.rs:10:17 | LL | type Next = as Next>::Next; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`) -note: required for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` - --> $DIR/issue-23122-2.rs:9:15 - | -LL | impl Next for GetNext { - | ^^^^ ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr index 07f828475680f..ea49e82ac7ac9 100644 --- a/src/test/ui/recursion/issue-83150.stderr +++ b/src/test/ui/recursion/issue-83150.stderr @@ -9,10 +9,12 @@ LL | func(&mut iter.map(|x| x + 1)) = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose -error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>: Iterator` +error[E0275]: overflow evaluating the requirement ` as Iterator>::Item` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) - = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator` + = note: required because of the requirements on the impl of `Iterator` for `Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` + = note: 64 redundant requirements hidden + = note: required because of the requirements on the impl of `Iterator` for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/recursion/issue-95134.rs b/src/test/ui/recursion/issue-95134.rs new file mode 100644 index 0000000000000..adc9c6ee2d967 --- /dev/null +++ b/src/test/ui/recursion/issue-95134.rs @@ -0,0 +1,28 @@ +// build-fail +// compile-flags: -Copt-level=0 +//~^^ ERROR overflow evaluating the requirement + +pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + if n > 15 { + encode_num(n / 16, &mut writer)?; + } + Ok(()) +} + +pub trait ExampleWriter { + type Error; +} + +impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T { + type Error = T::Error; +} + +struct EmptyWriter; + +impl ExampleWriter for EmptyWriter { + type Error = (); +} + +fn main() { + encode_num(69, &mut EmptyWriter).unwrap(); +} diff --git a/src/test/ui/recursion/issue-95134.stderr b/src/test/ui/recursion/issue-95134.stderr new file mode 100644 index 0000000000000..57a498694b7c1 --- /dev/null +++ b/src/test/ui/recursion/issue-95134.stderr @@ -0,0 +1,7 @@ +error[E0275]: overflow evaluating the requirement `::Error` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_95134`) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. From 4b47686e10caafebab36445072a17b6a0d4b99c7 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Fri, 19 Aug 2022 17:43:20 +0300 Subject: [PATCH 05/23] Update issue-83150.stderr --- src/test/ui/recursion/issue-83150.stderr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr index ea49e82ac7ac9..32f25faf3e8ba 100644 --- a/src/test/ui/recursion/issue-83150.stderr +++ b/src/test/ui/recursion/issue-83150.stderr @@ -12,9 +12,9 @@ LL | func(&mut iter.map(|x| x + 1)) error[E0275]: overflow evaluating the requirement ` as Iterator>::Item` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) - = note: required because of the requirements on the impl of `Iterator` for `Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` + = note: required for `Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator` = note: 64 redundant requirements hidden - = note: required because of the requirements on the impl of `Iterator` for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` + = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator` error: aborting due to previous error; 1 warning emitted From 17ddcb434b8fca7eeb865985942b146647a3510f Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Sat, 30 Apr 2022 12:01:31 -0500 Subject: [PATCH 06/23] Improve primitive/std docs separation and headers --- library/alloc/src/boxed.rs | 2 +- library/alloc/src/slice.rs | 80 ++---------------------------- library/alloc/src/str.rs | 22 +------- library/core/src/any.rs | 5 +- library/core/src/array/mod.rs | 2 +- library/core/src/borrow.rs | 2 +- library/core/src/char/mod.rs | 4 +- library/core/src/cmp.rs | 4 +- library/core/src/default.rs | 2 +- library/core/src/num/f32.rs | 2 +- library/core/src/num/f64.rs | 2 +- library/core/src/primitive_docs.rs | 61 ++++++++++++++++++++--- library/std/src/error.rs | 2 +- library/std/src/f32.rs | 2 +- library/std/src/f64.rs | 2 +- library/std/src/primitive_docs.rs | 61 ++++++++++++++++++++--- 16 files changed, 127 insertions(+), 128 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index c1ceeb0deb837..6955d863c99e7 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1,4 +1,4 @@ -//! A pointer type for heap allocation. +//! The `Box` type for heap allocation. //! //! [`Box`], casually referred to as a 'box', provides the simplest form of //! heap allocation in Rust. Boxes provide ownership for this allocation, and diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 63d4d94529008..2bc08f86def1e 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -1,82 +1,12 @@ -//! A dynamically-sized view into a contiguous sequence, `[T]`. +//! Utilities for the slice primitive type. //! //! *[See also the slice primitive type](slice).* //! -//! Slices are a view into a block of memory represented as a pointer and a -//! length. +//! Most of the structs in this module are iterator types which can only be created +//! using a certain function. For example, `slice.iter()` yields an [`Iter`]. //! -//! ``` -//! // slicing a Vec -//! let vec = vec![1, 2, 3]; -//! let int_slice = &vec[..]; -//! // coercing an array to a slice -//! let str_slice: &[&str] = &["one", "two", "three"]; -//! ``` -//! -//! Slices are either mutable or shared. The shared slice type is `&[T]`, -//! while the mutable slice type is `&mut [T]`, where `T` represents the element -//! type. For example, you can mutate the block of memory that a mutable slice -//! points to: -//! -//! ``` -//! let x = &mut [1, 2, 3]; -//! x[1] = 7; -//! assert_eq!(x, &[1, 7, 3]); -//! ``` -//! -//! Here are some of the things this module contains: -//! -//! ## Structs -//! -//! There are several structs that are useful for slices, such as [`Iter`], which -//! represents iteration over a slice. -//! -//! ## Trait Implementations -//! -//! There are several implementations of common traits for slices. Some examples -//! include: -//! -//! * [`Clone`] -//! * [`Eq`], [`Ord`] - for slices whose element type are [`Eq`] or [`Ord`]. -//! * [`Hash`] - for slices whose element type is [`Hash`]. -//! -//! ## Iteration -//! -//! The slices implement `IntoIterator`. The iterator yields references to the -//! slice elements. -//! -//! ``` -//! let numbers = &[0, 1, 2]; -//! for n in numbers { -//! println!("{n} is a number!"); -//! } -//! ``` -//! -//! The mutable slice yields mutable references to the elements: -//! -//! ``` -//! let mut scores = [7, 8, 9]; -//! for score in &mut scores[..] { -//! *score += 1; -//! } -//! ``` -//! -//! This iterator yields mutable references to the slice's elements, so while -//! the element type of the slice is `i32`, the element type of the iterator is -//! `&mut i32`. -//! -//! * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default -//! iterators. -//! * Further methods that return iterators are [`.split`], [`.splitn`], -//! [`.chunks`], [`.windows`] and more. -//! -//! [`Hash`]: core::hash::Hash -//! [`.iter`]: slice::iter -//! [`.iter_mut`]: slice::iter_mut -//! [`.split`]: slice::split -//! [`.splitn`]: slice::splitn -//! [`.chunks`]: slice::chunks -//! [`.windows`]: slice::windows +//! A few functions are provided to create a slice from a value reference +//! or from a raw pointer. #![stable(feature = "rust1", since = "1.0.0")] // Many of the usings in this module are only used in the test configuration. // It's cleaner to just turn off the unused_imports warning than to fix them. diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index d5ed2c4adf4f1..101dd1e57ec4d 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -1,26 +1,6 @@ -//! Unicode string slices. +//! Utilities for the `str` primitive type. //! //! *[See also the `str` primitive type](str).* -//! -//! The `&str` type is one of the two main string types, the other being `String`. -//! Unlike its `String` counterpart, its contents are borrowed. -//! -//! # Basic Usage -//! -//! A basic string declaration of `&str` type: -//! -//! ``` -//! let hello_world = "Hello, World!"; -//! ``` -//! -//! Here we have declared a string literal, also known as a string slice. -//! String literals have a static lifetime, which means the string `hello_world` -//! is guaranteed to be valid for the duration of the entire program. -//! We can explicitly specify `hello_world`'s lifetime as well: -//! -//! ``` -//! let hello_world: &'static str = "Hello, world!"; -//! ``` #![stable(feature = "rust1", since = "1.0.0")] // Many of the usings in this module are only used in the test configuration. diff --git a/library/core/src/any.rs b/library/core/src/any.rs index f20c497a183b2..e54f6c912d594 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -1,7 +1,4 @@ -//! This module contains the `Any` trait, which enables dynamic typing -//! of any `'static` type through runtime reflection. It also contains the -//! `Provider` trait and accompanying API, which enable trait objects to provide -//! data based on typed requests, an alternate form of runtime reflection. +//! Utilities for dynamic typing or type reflection. //! //! # `Any` and `TypeId` //! diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index c9823a136bc42..db5bfcab9d2b1 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -1,4 +1,4 @@ -//! Helper functions and types for fixed-length arrays. +//! Utilities for the array primitive type. //! //! *[See also the array primitive type](array).* diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs index 58eabecf3f091..8378611eb18c3 100644 --- a/library/core/src/borrow.rs +++ b/library/core/src/borrow.rs @@ -1,4 +1,4 @@ -//! A module for working with borrowed data. +//! Utilities for working with borrowed data. #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index 0df23e7bbe695..a4bdd38f65530 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -1,4 +1,6 @@ -//! A character type. +//! Utilities for the `char` primitive type. +//! +//! *[See also the `char` primitive type](primitive@char).* //! //! The `char` type represents a single character. More specifically, since //! 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 5ca5b5fde1604..8a30bb6745060 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1,6 +1,6 @@ -//! Functionality for ordering and comparison. +//! Utilities for comparing and ordering values. //! -//! This module contains various tools for ordering and comparing values. In +//! This module contains various tools for comparing and ordering values. In //! summary: //! //! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 1ce00828bf344..b53cd6074b532 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -1,4 +1,4 @@ -//! The `Default` trait for types which may have meaningful default values. +//! The `Default` trait for types with a default value. #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 23c46f1a74a31..94a8a1ec79284 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1,4 +1,4 @@ -//! Constants specific to the `f32` single-precision floating point type. +//! Constants for the `f32` single-precision floating point type. //! //! *[See also the `f32` primitive type][f32].* //! diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index b5c8241d2943d..bc278fa806927 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1,4 +1,4 @@ -//! Constants specific to the `f64` double-precision floating point type. +//! Constants for the `f64` double-precision floating point type. //! //! *[See also the `f64` primitive type][f64].* //! diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 1c14b9341cac8..2b2ef64fdb1c3 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -801,11 +801,53 @@ mod prim_array {} /// assert_eq!(2 * pointer_size, std::mem::size_of::>()); /// assert_eq!(2 * pointer_size, std::mem::size_of::>()); /// ``` +/// +/// ## Trait Implementations +/// +/// Some traits are implemented for slices if the element type implements +/// that trait. This includes [`Eq`], [`Hash`] and [`Ord`]. +/// +/// ## Iteration +/// +/// The slices implement `IntoIterator`. The iterator yields references to the +/// slice elements. +/// +/// ``` +/// let numbers: &[i32] = &[0, 1, 2]; +/// for n in numbers { +/// println!("{n} is a number!"); +/// } +/// ``` +/// +/// The mutable slice yields mutable references to the elements: +/// +/// ``` +/// let mut scores: &mut [i32] = &mut [7, 8, 9]; +/// for score in scores { +/// *score += 1; +/// } +/// ``` +/// +/// This iterator yields mutable references to the slice's elements, so while +/// the element type of the slice is `i32`, the element type of the iterator is +/// `&mut i32`. +/// +/// * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default +/// iterators. +/// * Further methods that return iterators are [`.split`], [`.splitn`], +/// [`.chunks`], [`.windows`] and more. +/// +/// [`Hash`]: core::hash::Hash +/// [`.iter`]: slice::iter +/// [`.iter_mut`]: slice::iter_mut +/// [`.split`]: slice::split +/// [`.splitn`]: slice::splitn +/// [`.chunks`]: slice::chunks +/// [`.windows`]: slice::windows #[stable(feature = "rust1", since = "1.0.0")] mod prim_slice {} #[doc(primitive = "str")] -// /// String slices. /// /// *[See also the `std::str` module](crate::str).* @@ -816,19 +858,22 @@ mod prim_slice {} /// /// String slices are always valid UTF-8. /// -/// # Examples +/// # Basic Usage /// /// String literals are string slices: /// /// ``` -/// let hello = "Hello, world!"; -/// -/// // with an explicit type annotation -/// let hello: &'static str = "Hello, world!"; +/// let hello_world = "Hello, World!"; /// ``` /// -/// They are `'static` because they're stored directly in the final binary, and -/// so will be valid for the `'static` duration. +/// Here we have declared a string slice initialized with a string literal. +/// String literals have a static lifetime, which means the string `hello_world` +/// is guaranteed to be valid for the duration of the entire program. +/// We can explicitly specify `hello_world`'s lifetime as well: +/// +/// ``` +/// let hello_world: &'static str = "Hello, world!"; +/// ``` /// /// # Representation /// diff --git a/library/std/src/error.rs b/library/std/src/error.rs index df7a49d258282..4fbcfd85d7c04 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -1,4 +1,4 @@ -//! Interfaces for working with Errors. +//! The `Error` trait provides common functionality for errors. //! //! # Error Handling In Rust //! diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 933b52b4dccbb..3dd5b12507fb2 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -1,4 +1,4 @@ -//! Constants specific to the `f32` single-precision floating point type. +//! Constants for the `f32` single-precision floating point type. //! //! *[See also the `f32` primitive type](primitive@f32).* //! diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index a9aa84f70d19e..31351a87978c9 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -1,4 +1,4 @@ -//! Constants specific to the `f64` double-precision floating point type. +//! Constants for the `f64` double-precision floating point type. //! //! *[See also the `f64` primitive type](primitive@f64).* //! diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 1c14b9341cac8..2b2ef64fdb1c3 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -801,11 +801,53 @@ mod prim_array {} /// assert_eq!(2 * pointer_size, std::mem::size_of::>()); /// assert_eq!(2 * pointer_size, std::mem::size_of::>()); /// ``` +/// +/// ## Trait Implementations +/// +/// Some traits are implemented for slices if the element type implements +/// that trait. This includes [`Eq`], [`Hash`] and [`Ord`]. +/// +/// ## Iteration +/// +/// The slices implement `IntoIterator`. The iterator yields references to the +/// slice elements. +/// +/// ``` +/// let numbers: &[i32] = &[0, 1, 2]; +/// for n in numbers { +/// println!("{n} is a number!"); +/// } +/// ``` +/// +/// The mutable slice yields mutable references to the elements: +/// +/// ``` +/// let mut scores: &mut [i32] = &mut [7, 8, 9]; +/// for score in scores { +/// *score += 1; +/// } +/// ``` +/// +/// This iterator yields mutable references to the slice's elements, so while +/// the element type of the slice is `i32`, the element type of the iterator is +/// `&mut i32`. +/// +/// * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default +/// iterators. +/// * Further methods that return iterators are [`.split`], [`.splitn`], +/// [`.chunks`], [`.windows`] and more. +/// +/// [`Hash`]: core::hash::Hash +/// [`.iter`]: slice::iter +/// [`.iter_mut`]: slice::iter_mut +/// [`.split`]: slice::split +/// [`.splitn`]: slice::splitn +/// [`.chunks`]: slice::chunks +/// [`.windows`]: slice::windows #[stable(feature = "rust1", since = "1.0.0")] mod prim_slice {} #[doc(primitive = "str")] -// /// String slices. /// /// *[See also the `std::str` module](crate::str).* @@ -816,19 +858,22 @@ mod prim_slice {} /// /// String slices are always valid UTF-8. /// -/// # Examples +/// # Basic Usage /// /// String literals are string slices: /// /// ``` -/// let hello = "Hello, world!"; -/// -/// // with an explicit type annotation -/// let hello: &'static str = "Hello, world!"; +/// let hello_world = "Hello, World!"; /// ``` /// -/// They are `'static` because they're stored directly in the final binary, and -/// so will be valid for the `'static` duration. +/// Here we have declared a string slice initialized with a string literal. +/// String literals have a static lifetime, which means the string `hello_world` +/// is guaranteed to be valid for the duration of the entire program. +/// We can explicitly specify `hello_world`'s lifetime as well: +/// +/// ``` +/// let hello_world: &'static str = "Hello, world!"; +/// ``` /// /// # Representation /// From 5d5e451618d3f364ce4a19d1d2c4f8903bc30dde Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 21 Aug 2022 14:58:42 +0400 Subject: [PATCH 07/23] recover `const Tr` bounds (no `~`) --- compiler/rustc_parse/src/parser/ty.rs | 14 ++++++++++++++ .../ui/rfc-2632-const-trait-impl/without-tilde.rs | 3 +-- .../rfc-2632-const-trait-impl/without-tilde.stderr | 14 +++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index b76ba8ff2d98c..298198f2cf7d7 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -809,6 +809,20 @@ impl<'a> Parser<'a> { self.expect_keyword(kw::Const)?; let span = tilde.to(self.prev_token.span); self.sess.gated_spans.gate(sym::const_trait_impl, span); + Some(span) + } else if self.eat_keyword(kw::Const) { + let span = self.prev_token.span; + self.sess.gated_spans.gate(sym::const_trait_impl, span); + + self.struct_span_err(span, "const bounds must start with `~`") + .span_suggestion( + span.shrink_to_lo(), + "add `~`", + "~", + Applicability::MachineApplicable, + ) + .emit(); + Some(span) } else { None diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs index e0d3e0b497b3f..d63381b5f2cc9 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs @@ -3,5 +3,4 @@ #![feature(const_trait_impl)] struct S; -//~^ ERROR expected identifier, found keyword `const` -//~| ERROR expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr` +//~^ ERROR const bounds must start with `~` diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr index 243f0979509bf..31300354a5737 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr @@ -1,14 +1,10 @@ -error: expected identifier, found keyword `const` +error: const bounds must start with `~` --> $DIR/without-tilde.rs:5:13 | LL | struct S; - | ^^^^^ expected identifier, found keyword + | -^^^^ + | | + | help: add `~`: `~` -error: expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr` - --> $DIR/without-tilde.rs:5:19 - | -LL | struct S; - | ^^ expected one of 7 possible tokens - -error: aborting due to 2 previous errors +error: aborting due to previous error From d6fdf14eb783969b4e20e91d39a97bb56b50f1c6 Mon Sep 17 00:00:00 2001 From: finalchild Date: Wed, 17 Aug 2022 23:51:01 +0900 Subject: [PATCH 08/23] Migrate forbidden_let --- Cargo.lock | 1 + compiler/rustc_ast_passes/Cargo.toml | 1 + .../rustc_ast_passes/src/ast_validation.rs | 22 +++---------- compiler/rustc_ast_passes/src/errors.rs | 32 +++++++++++++++++++ compiler/rustc_ast_passes/src/lib.rs | 1 + .../locales/en-US/ast_passes.ftl | 5 +++ compiler/rustc_error_messages/src/lib.rs | 1 + 7 files changed, 45 insertions(+), 18 deletions(-) create mode 100644 compiler/rustc_ast_passes/src/errors.rs create mode 100644 compiler/rustc_error_messages/locales/en-US/ast_passes.ftl diff --git a/Cargo.lock b/Cargo.lock index 3a35985836c93..cb245ce0ff828 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3595,6 +3595,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_macros", "rustc_parse", "rustc_session", "rustc_span", diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 22742b2adbd4f..37eff9207c128 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -11,6 +11,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_macros = { path = "../rustc_macros" } rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index e61dfef7bd380..f8eca6a933711 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -27,6 +27,8 @@ use rustc_target::spec::abi; use std::mem; use std::ops::{Deref, DerefMut}; +use crate::errors::ForbiddenLet; + const MORE_EXTERN: &str = "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html"; @@ -117,23 +119,7 @@ impl<'a> AstValidator<'a> { /// Emits an error banning the `let` expression provided in the given location. fn ban_let_expr(&self, expr: &'a Expr, forbidden_let_reason: ForbiddenLetReason) { - let err = "`let` expressions are not supported here"; - let mut diag = self.session.struct_span_err(expr.span, err); - diag.note("only supported directly in conditions of `if` and `while` expressions"); - match forbidden_let_reason { - ForbiddenLetReason::GenericForbidden => {} - ForbiddenLetReason::NotSupportedOr(span) => { - diag.span_note(span, "`||` operators are not supported in let chain expressions"); - } - ForbiddenLetReason::NotSupportedParentheses(span) => { - diag.span_note( - span, - "`let`s wrapped in parentheses are not supported in a context with let \ - chains", - ); - } - } - diag.emit(); + self.session.emit_err(ForbiddenLet { span: expr.span, reason: forbidden_let_reason }); } fn check_gat_where( @@ -1876,7 +1862,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> /// Used to forbid `let` expressions in certain syntactic locations. #[derive(Clone, Copy)] -enum ForbiddenLetReason { +pub(crate) enum ForbiddenLetReason { /// `let` is not valid and the source environment is not important GenericForbidden, /// A let chain with the `||` operator diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs new file mode 100644 index 0000000000000..397acd3b60912 --- /dev/null +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -0,0 +1,32 @@ +//! Errors emitted by ast_passes. + +use rustc_errors::fluent; +use rustc_errors::{AddSubdiagnostic, Diagnostic}; +use rustc_macros::SessionDiagnostic; +use rustc_span::Span; + +use crate::ast_validation::ForbiddenLetReason; + +#[derive(SessionDiagnostic)] +#[error(ast_passes::forbidden_let)] +#[note] +pub struct ForbiddenLet { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub(crate) reason: ForbiddenLetReason, +} + +impl AddSubdiagnostic for ForbiddenLetReason { + fn add_to_diagnostic(self, diag: &mut Diagnostic) { + match self { + Self::GenericForbidden => {} + Self::NotSupportedOr(span) => { + diag.span_note(span, fluent::ast_passes::not_supported_or); + } + Self::NotSupportedParentheses(span) => { + diag.span_note(span, fluent::ast_passes::not_supported_parentheses); + }, + } + } +} diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 2bc3b6f361643..6a8262989850c 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -12,6 +12,7 @@ #![recursion_limit = "256"] pub mod ast_validation; +mod errors; pub mod feature_gate; pub mod node_count; pub mod show_span; diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl new file mode 100644 index 0000000000000..4f4235b6c8155 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -0,0 +1,5 @@ +ast_passes_forbidden_let = + `let` expressions are not supported here + .note = only supported directly in conditions of `if` and `while` expressions + .not_supported_or = `||` operators are not supported in let chain expressions + .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index ee978f04be2a5..3569c7f063064 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -32,6 +32,7 @@ pub use unic_langid::{langid, LanguageIdentifier}; // Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module. fluent_messages! { + ast_passes => "../locales/en-US/ast_passes.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", const_eval => "../locales/en-US/const_eval.ftl", From 80451de390dde969057230345e44adfab21de6b8 Mon Sep 17 00:00:00 2001 From: finalchild Date: Wed, 17 Aug 2022 23:52:16 +0900 Subject: [PATCH 09/23] Use DiagnosticMessage for BufferedEarlyLint.msg --- compiler/rustc_builtin_macros/src/format.rs | 2 +- compiler/rustc_lint/src/early.rs | 2 +- compiler/rustc_lint_defs/src/lib.rs | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 08026c9d35784..e76f5711b7b63 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -1176,7 +1176,7 @@ fn create_lints_for_named_arguments_used_positionally(cx: &mut Context<'_, '_>) cx.ecx.buffered_early_lint.push(BufferedEarlyLint { span: MultiSpan::from_span(named_arg.positional_named_arg_span), - msg: msg.clone(), + msg: msg.clone().into(), node_id: ast::CRATE_NODE_ID, lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY), diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally { diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 580a4566869f0..cdb5b3c4284a8 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -45,7 +45,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { lint_id.lint, Some(span), |lint| { - lint.build(&msg).emit(); + lint.build(msg).emit(); }, diagnostic, ); diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index a826f599e9cd5..32b653f669bd1 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -9,7 +9,7 @@ pub use self::Level::*; use rustc_ast::node_id::{NodeId, NodeMap}; use rustc_ast::{AttrId, Attribute}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; -use rustc_error_messages::MultiSpan; +use rustc_error_messages::{MultiSpan, DiagnosticMessage}; use rustc_hir::HashStableContext; use rustc_hir::HirId; use rustc_span::edition::Edition; @@ -491,7 +491,7 @@ pub struct BufferedEarlyLint { pub span: MultiSpan, /// The lint message. - pub msg: String, + pub msg: DiagnosticMessage, /// The `NodeId` of the AST node that generated the lint. pub node_id: NodeId, @@ -520,11 +520,11 @@ impl LintBuffer { lint: &'static Lint, node_id: NodeId, span: MultiSpan, - msg: &str, + msg: impl Into, diagnostic: BuiltinLintDiagnostics, ) { let lint_id = LintId::of(lint); - let msg = msg.to_string(); + let msg = msg.into(); self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, msg, diagnostic }); } From e144a2367aab5c628752580de8a4f625b08ea6f3 Mon Sep 17 00:00:00 2001 From: finalchild Date: Thu, 18 Aug 2022 04:36:57 +0900 Subject: [PATCH 10/23] Migrate deprecated_where_clause_location, forbidden_assoc_constraint, keyword_lifetime, invalid_label, invalid_visibility --- .../rustc_ast_passes/src/ast_validation.rs | 36 ++++++--------- compiler/rustc_ast_passes/src/errors.rs | 45 ++++++++++++++++++- .../locales/en-US/ast_passes.ftl | 18 ++++++++ compiler/rustc_lint_defs/src/lib.rs | 4 +- 4 files changed, 77 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index f8eca6a933711..fee876489f7ee 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -13,7 +13,7 @@ use rustc_ast::walk_list; use rustc_ast::*; use rustc_ast_pretty::pprust::{self, State}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{error_code, pluralize, struct_span_err, Applicability, Diagnostic}; +use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability, Diagnostic}; use rustc_parse::validate_attr; use rustc_session::lint::builtin::{ DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY, @@ -27,7 +27,7 @@ use rustc_target::spec::abi; use std::mem; use std::ops::{Deref, DerefMut}; -use crate::errors::ForbiddenLet; +use crate::errors::*; const MORE_EXTERN: &str = "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html"; @@ -149,7 +149,7 @@ impl<'a> AstValidator<'a> { DEPRECATED_WHERE_CLAUSE_LOCATION, id, where_clauses.0.1, - "where clause not allowed here", + fluent::ast_passes::deprecated_where_clause_location, BuiltinLintDiagnostics::DeprecatedWhereclauseLocation( where_clauses.1.1.shrink_to_hi(), suggestion, @@ -179,10 +179,7 @@ impl<'a> AstValidator<'a> { AssocConstraintKind::Equality { .. } => {} AssocConstraintKind::Bound { .. } => { if self.is_assoc_ty_bound_banned { - self.err_handler().span_err( - constraint.span, - "associated type bounds are not allowed within structs, enums, or unions", - ); + self.session.emit_err(ForbiddenAssocConstraint { span: constraint.span }); } } } @@ -254,31 +251,26 @@ impl<'a> AstValidator<'a> { fn check_lifetime(&self, ident: Ident) { let valid_names = [kw::UnderscoreLifetime, kw::StaticLifetime, kw::Empty]; if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() { - self.err_handler().span_err(ident.span, "lifetimes cannot use keyword names"); + self.session.emit_err(KeywordLifetime { span: ident.span }); } } fn check_label(&self, ident: Ident) { if ident.without_first_quote().is_reserved() { - self.err_handler() - .span_err(ident.span, &format!("invalid label name `{}`", ident.name)); + self.session.emit_err(InvalidLabel { span: ident.span, name: ident.name }); } } - fn invalid_visibility(&self, vis: &Visibility, note: Option<&str>) { + fn invalid_visibility(&self, vis: &Visibility, note: Option) { if let VisibilityKind::Inherited = vis.kind { return; } - let mut err = - struct_span_err!(self.session, vis.span, E0449, "unnecessary visibility qualifier"); - if vis.kind.is_pub() { - err.span_label(vis.span, "`pub` not permitted here because it's implied"); - } - if let Some(note) = note { - err.note(note); - } - err.emit(); + self.session.emit_err(InvalidVisibility { + span: vis.span, + implied: if vis.kind.is_pub() { Some(vis.span) } else { None }, + note, + }); } fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option, bool)) { @@ -1154,7 +1146,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.invalid_visibility( &item.vis, - Some("place qualifiers on individual impl items instead"), + Some(InvalidVisibilityNote::IndividualImplItems), ); if let Unsafe::Yes(span) = unsafety { error(span, "unsafe").code(error_code!(E0197)).emit(); @@ -1222,7 +1214,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { let old_item = mem::replace(&mut self.extern_mod, Some(item)); self.invalid_visibility( &item.vis, - Some("place qualifiers on individual foreign items instead"), + Some(InvalidVisibilityNote::IndividualForeignItems), ); if let Unsafe::Yes(span) = unsafety { self.err_handler().span_err(span, "extern block cannot be declared unsafe"); diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 397acd3b60912..0d5a41771ea88 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -2,8 +2,8 @@ use rustc_errors::fluent; use rustc_errors::{AddSubdiagnostic, Diagnostic}; -use rustc_macros::SessionDiagnostic; -use rustc_span::Span; +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use rustc_span::{Span, Symbol}; use crate::ast_validation::ForbiddenLetReason; @@ -30,3 +30,44 @@ impl AddSubdiagnostic for ForbiddenLetReason { } } } + +#[derive(SessionDiagnostic)] +#[error(ast_passes::forbidden_assoc_constraint)] +pub struct ForbiddenAssocConstraint { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::keyword_lifetime)] +pub struct KeywordLifetime { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::invalid_label)] +pub struct InvalidLabel { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::invalid_visibility, code = "E0449")] +pub struct InvalidVisibility { + #[primary_span] + pub span: Span, + #[label(ast_passes::implied)] + pub implied: Option, + #[subdiagnostic] + pub note: Option, +} + +#[derive(SessionSubdiagnostic)] +pub enum InvalidVisibilityNote { + #[note(ast_passes::individual_impl_items)] + IndividualImplItems, + #[note(ast_passes::individual_foreign_items)] + IndividualForeignItems, +} diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl index 4f4235b6c8155..153a91cc7e2bb 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -3,3 +3,21 @@ ast_passes_forbidden_let = .note = only supported directly in conditions of `if` and `while` expressions .not_supported_or = `||` operators are not supported in let chain expressions .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains + +ast_passes_deprecated_where_clause_location = + where clause not allowed here + +ast_passes_forbidden_assoc_constraint = + associated type bounds are not allowed within structs, enums, or unions + +ast_passes_keyword_lifetime = + lifetimes cannot use keyword names + +ast_passes_invalid_label = + invalid label name `{$name}` + +ast_passes_invalid_visibility = + unnecessary visibility qualifier + .implied = `pub` not permitted here because it's implied + .individual_impl_items = place qualifiers on individual impl items instead + .individual_foreign_items = place qualifiers on individual foreign items instead diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 32b653f669bd1..609a7894d8605 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -537,7 +537,7 @@ impl LintBuffer { lint: &'static Lint, id: NodeId, sp: impl Into, - msg: &str, + msg: impl Into, ) { self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal) } @@ -547,7 +547,7 @@ impl LintBuffer { lint: &'static Lint, id: NodeId, sp: impl Into, - msg: &str, + msg: impl Into, diagnostic: BuiltinLintDiagnostics, ) { self.add_lint(lint, id, sp.into(), msg, diagnostic) From 88afae5d1adf809510aee801cab639d5ef484713 Mon Sep 17 00:00:00 2001 From: finalchild Date: Thu, 18 Aug 2022 15:23:00 +0900 Subject: [PATCH 11/23] Tidy --- compiler/rustc_ast_passes/src/errors.rs | 2 +- compiler/rustc_lint_defs/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 0d5a41771ea88..8bea95ea092dd 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -26,7 +26,7 @@ impl AddSubdiagnostic for ForbiddenLetReason { } Self::NotSupportedParentheses(span) => { diag.span_note(span, fluent::ast_passes::not_supported_parentheses); - }, + } } } } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 609a7894d8605..9e7cbba9511b2 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -9,7 +9,7 @@ pub use self::Level::*; use rustc_ast::node_id::{NodeId, NodeMap}; use rustc_ast::{AttrId, Attribute}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; -use rustc_error_messages::{MultiSpan, DiagnosticMessage}; +use rustc_error_messages::{DiagnosticMessage, MultiSpan}; use rustc_hir::HashStableContext; use rustc_hir::HirId; use rustc_span::edition::Edition; From e3d4c4039a3b041c7610735c641e5688c25af8b2 Mon Sep 17 00:00:00 2001 From: finalchild Date: Thu, 18 Aug 2022 16:49:52 +0900 Subject: [PATCH 12/23] Migrate trait_fn_async --- compiler/rustc_ast_passes/src/ast_validation.rs | 11 +---------- compiler/rustc_ast_passes/src/errors.rs | 11 +++++++++++ .../rustc_error_messages/locales/en-US/ast_passes.ftl | 6 ++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index fee876489f7ee..234243f372c25 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -287,16 +287,7 @@ impl<'a> AstValidator<'a> { fn check_trait_fn_not_async(&self, fn_span: Span, asyncness: Async) { if let Async::Yes { span, .. } = asyncness { - struct_span_err!( - self.session, - fn_span, - E0706, - "functions in traits cannot be declared `async`" - ) - .span_label(span, "`async` because of this") - .note("`async` trait functions are not currently supported") - .note("consider using the `async-trait` crate: https://crates.io/crates/async-trait") - .emit(); + self.session.emit_err(TraitFnAsync { fn_span, span }); } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 8bea95ea092dd..ed44beafff21a 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -71,3 +71,14 @@ pub enum InvalidVisibilityNote { #[note(ast_passes::individual_foreign_items)] IndividualForeignItems, } + +#[derive(SessionDiagnostic)] +#[error(ast_passes::trait_fn_async, code = "E0706")] +#[note] +#[note(ast_passes::note2)] +pub struct TraitFnAsync { + #[primary_span] + pub fn_span: Span, + #[label] + pub span: Span, +} diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl index 153a91cc7e2bb..ab2313fd86cd8 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -21,3 +21,9 @@ ast_passes_invalid_visibility = .implied = `pub` not permitted here because it's implied .individual_impl_items = place qualifiers on individual impl items instead .individual_foreign_items = place qualifiers on individual foreign items instead + +ast_passes_trait_fn_async = + functions in traits cannot be declared `async` + .label = `async` because of this + .note = `async` trait functions are not currently supported + .note2 = consider using the `async-trait` crate: https://crates.io/crates/async-trait From 8d042f4483b60ceaa98a6bb2a778fa5ac4226bbe Mon Sep 17 00:00:00 2001 From: finalchild Date: Thu, 18 Aug 2022 16:57:25 +0900 Subject: [PATCH 13/23] Migrate trait_fn_const --- compiler/rustc_ast_passes/src/errors.rs | 8 ++++++++ .../rustc_error_messages/locales/en-US/ast_passes.ftl | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index ed44beafff21a..7a7073b5a5107 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -82,3 +82,11 @@ pub struct TraitFnAsync { #[label] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[error(ast_passes::trait_fn_const, code = "E0379")] +pub struct TraitFnConst { + #[primary_span] + #[label] + pub span: Span, +} diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl index ab2313fd86cd8..fa6a02493f3b7 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -27,3 +27,7 @@ ast_passes_trait_fn_async = .label = `async` because of this .note = `async` trait functions are not currently supported .note2 = consider using the `async-trait` crate: https://crates.io/crates/async-trait + +ast_passes_trait_fn_const = + functions in traits cannot be declared const + .label = functions in traits cannot be const From 269c85390c7eac7e9708a1d5529e54e10bd9631a Mon Sep 17 00:00:00 2001 From: finalchild Date: Thu, 18 Aug 2022 17:38:11 +0900 Subject: [PATCH 14/23] Migrate forbidden_lifetime_bound, forbidden_non_lifetime_param, too_many_params, c_var_args_without_named_arg, c_var_args_not_last --- .../rustc_ast_passes/src/ast_validation.rs | 32 ++++------------- compiler/rustc_ast_passes/src/errors.rs | 36 +++++++++++++++++++ .../locales/en-US/ast_passes.ftl | 15 ++++++++ 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 234243f372c25..7735d95f71ee9 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -293,14 +293,7 @@ impl<'a> AstValidator<'a> { fn check_trait_fn_not_const(&self, constness: Const) { if let Const::Yes(span) = constness { - struct_span_err!( - self.session, - span, - E0379, - "functions in traits cannot be declared const" - ) - .span_label(span, "functions in traits cannot be const") - .emit(); + self.session.emit_err(TraitFnConst { span }); } } @@ -313,8 +306,7 @@ impl<'a> AstValidator<'a> { GenericParamKind::Lifetime { .. } => { if !param.bounds.is_empty() { let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect(); - self.err_handler() - .span_err(spans, "lifetime bounds cannot be used in this context"); + self.session.emit_err(ForbiddenLifetimeBound { spans }); } None } @@ -322,10 +314,7 @@ impl<'a> AstValidator<'a> { }) .collect(); if !non_lt_param_spans.is_empty() { - self.err_handler().span_err( - non_lt_param_spans, - "only lifetime parameters can be used in this context", - ); + self.session.emit_err(ForbiddenNonLifetimeParam { spans: non_lt_param_spans }); } } @@ -342,10 +331,7 @@ impl<'a> AstValidator<'a> { let max_num_args: usize = u16::MAX.into(); if fn_decl.inputs.len() > max_num_args { let Param { span, .. } = fn_decl.inputs[0]; - self.err_handler().span_fatal( - span, - &format!("function can not have more than {} arguments", max_num_args), - ); + self.session.emit_err(TooManyParams { span, max_num_args }); } } @@ -353,19 +339,13 @@ impl<'a> AstValidator<'a> { match &*fn_decl.inputs { [Param { ty, span, .. }] => { if let TyKind::CVarArgs = ty.kind { - self.err_handler().span_err( - *span, - "C-variadic function must be declared with at least one named argument", - ); + self.session.emit_err(CVarArgsWithoutNamedArg { span: *span }); } } [ps @ .., _] => { for Param { ty, span, .. } in ps { if let TyKind::CVarArgs = ty.kind { - self.err_handler().span_err( - *span, - "`...` must be the last argument of a C-variadic function", - ); + self.session.emit_err(CVarArgsNotLast { span: *span }); } } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 7a7073b5a5107..cc92f00714de0 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -90,3 +90,39 @@ pub struct TraitFnConst { #[label] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[error(ast_passes::forbidden_lifetime_bound)] +pub struct ForbiddenLifetimeBound { + #[primary_span] + pub spans: Vec, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::forbidden_non_lifetime_param)] +pub struct ForbiddenNonLifetimeParam { + #[primary_span] + pub spans: Vec, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::too_many_params)] +pub struct TooManyParams { + #[primary_span] + pub span: Span, + pub max_num_args: usize, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::c_var_args_without_named_arg)] +pub struct CVarArgsWithoutNamedArg { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::c_var_args_not_last)] +pub struct CVarArgsNotLast { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl index fa6a02493f3b7..c0994063fc343 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -31,3 +31,18 @@ ast_passes_trait_fn_async = ast_passes_trait_fn_const = functions in traits cannot be declared const .label = functions in traits cannot be const + +ast_passes_forbidden_lifetime_bound = + lifetime bounds cannot be used in this context + +ast_passes_forbidden_non_lifetime_param = + only lifetime parameters can be used in this context + +ast_passes_too_many_params = + function can not have more than {$max_num_args} arguments + +ast_passes_c_var_args_without_named_arg = + C-variadic function must be declared with at least one named argument + +ast_passes_c_var_args_not_last = + `...` must be the last argument of a C-variadic function From c6903c04b1c95061680aafa9da7e8dbccabb9069 Mon Sep 17 00:00:00 2001 From: finalchild Date: Thu, 18 Aug 2022 17:46:01 +0900 Subject: [PATCH 15/23] Migrate doc_comment_on_fn_param, forbidden_attr_on_fn_param --- compiler/rustc_ast_passes/src/ast_validation.rs | 14 ++------------ compiler/rustc_ast_passes/src/errors.rs | 15 +++++++++++++++ .../locales/en-US/ast_passes.ftl | 7 +++++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 7735d95f71ee9..e42d716d5ae06 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -372,19 +372,9 @@ impl<'a> AstValidator<'a> { }) .for_each(|attr| { if attr.is_doc_comment() { - self.err_handler() - .struct_span_err( - attr.span, - "documentation comments cannot be applied to function parameters", - ) - .span_label(attr.span, "doc comments are not allowed here") - .emit(); + self.session.emit_err(DocCommentOnFnParam { span: attr.span }); } else { - self.err_handler().span_err( - attr.span, - "allow, cfg, cfg_attr, deny, expect, \ - forbid, and warn are the only allowed built-in attributes in function parameters", - ); + self.session.emit_err(ForbiddenAttrOnFnParam { span: attr.span }); } }); } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index cc92f00714de0..2b6d3d2a39a2e 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -126,3 +126,18 @@ pub struct CVarArgsNotLast { #[primary_span] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[error(ast_passes::doc_comment_on_fn_param)] +pub struct DocCommentOnFnParam { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::forbidden_attr_on_fn_param)] +pub struct ForbiddenAttrOnFnParam { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl index c0994063fc343..bca73baea0049 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -46,3 +46,10 @@ ast_passes_c_var_args_without_named_arg = ast_passes_c_var_args_not_last = `...` must be the last argument of a C-variadic function + +ast_passes_doc_comment_on_fn_param = + documentation comments cannot be applied to function parameters + .label = doc comments are not allowed here + +ast_passes_forbidden_attr_on_fn_param = + allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters From 07e0bc9600128aef1922cd67939c303d92b3fafc Mon Sep 17 00:00:00 2001 From: finalchild Date: Thu, 18 Aug 2022 17:53:59 +0900 Subject: [PATCH 16/23] Rename c_var_args_without_named_arg to c_var_args_is_sole_param --- compiler/rustc_ast_passes/src/ast_validation.rs | 2 +- compiler/rustc_ast_passes/src/errors.rs | 4 ++-- compiler/rustc_error_messages/locales/en-US/ast_passes.ftl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index e42d716d5ae06..3dd3cc537e6f1 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -339,7 +339,7 @@ impl<'a> AstValidator<'a> { match &*fn_decl.inputs { [Param { ty, span, .. }] => { if let TyKind::CVarArgs = ty.kind { - self.session.emit_err(CVarArgsWithoutNamedArg { span: *span }); + self.session.emit_err(CVarArgsIsSoleParam { span: *span }); } } [ps @ .., _] => { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 2b6d3d2a39a2e..d376f638bd2e1 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -114,8 +114,8 @@ pub struct TooManyParams { } #[derive(SessionDiagnostic)] -#[error(ast_passes::c_var_args_without_named_arg)] -pub struct CVarArgsWithoutNamedArg { +#[error(ast_passes::c_var_args_is_sole_param)] +pub struct CVarArgsIsSoleParam { #[primary_span] pub span: Span, } diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl index bca73baea0049..49ef0cc83de3d 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -41,7 +41,7 @@ ast_passes_forbidden_non_lifetime_param = ast_passes_too_many_params = function can not have more than {$max_num_args} arguments -ast_passes_c_var_args_without_named_arg = +ast_passes_c_var_args_is_sole_param = C-variadic function must be declared with at least one named argument ast_passes_c_var_args_not_last = From bfefefbcfa87cc468d081da371686432ca77c245 Mon Sep 17 00:00:00 2001 From: finalchild Date: Thu, 18 Aug 2022 18:20:14 +0900 Subject: [PATCH 17/23] Migrate fn_param_forbidden_self and rename others to have prefix fn_param_ --- .../rustc_ast_passes/src/ast_validation.rs | 19 ++++-------- compiler/rustc_ast_passes/src/errors.rs | 29 ++++++++++++------- .../locales/en-US/ast_passes.ftl | 15 ++++++---- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 3dd3cc537e6f1..1c3a4ab7c6764 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -331,7 +331,7 @@ impl<'a> AstValidator<'a> { let max_num_args: usize = u16::MAX.into(); if fn_decl.inputs.len() > max_num_args { let Param { span, .. } = fn_decl.inputs[0]; - self.session.emit_err(TooManyParams { span, max_num_args }); + self.session.emit_err(FnParamTooMany { span, max_num_args }); } } @@ -339,13 +339,13 @@ impl<'a> AstValidator<'a> { match &*fn_decl.inputs { [Param { ty, span, .. }] => { if let TyKind::CVarArgs = ty.kind { - self.session.emit_err(CVarArgsIsSoleParam { span: *span }); + self.session.emit_err(FnParamCVarArgsOnly { span: *span }); } } [ps @ .., _] => { for Param { ty, span, .. } in ps { if let TyKind::CVarArgs = ty.kind { - self.session.emit_err(CVarArgsNotLast { span: *span }); + self.session.emit_err(FnParamCVarArgsNotLast { span: *span }); } } } @@ -372,9 +372,9 @@ impl<'a> AstValidator<'a> { }) .for_each(|attr| { if attr.is_doc_comment() { - self.session.emit_err(DocCommentOnFnParam { span: attr.span }); + self.session.emit_err(FnParamDocComment { span: attr.span }); } else { - self.session.emit_err(ForbiddenAttrOnFnParam { span: attr.span }); + self.session.emit_err(FnParamForbiddenAttr { span: attr.span }); } }); } @@ -382,14 +382,7 @@ impl<'a> AstValidator<'a> { fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) { if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) { if param.is_self() { - self.err_handler() - .struct_span_err( - param.span, - "`self` parameter is only allowed in associated functions", - ) - .span_label(param.span, "not semantically valid as function parameter") - .note("associated functions are those in `impl` or `trait` definitions") - .emit(); + self.session.emit_err(FnParamForbiddenSelf { span: param.span }); } } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index d376f638bd2e1..ee375f1ced7e0 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -106,38 +106,47 @@ pub struct ForbiddenNonLifetimeParam { } #[derive(SessionDiagnostic)] -#[error(ast_passes::too_many_params)] -pub struct TooManyParams { +#[error(ast_passes::fn_param_too_many)] +pub struct FnParamTooMany { #[primary_span] pub span: Span, pub max_num_args: usize, } #[derive(SessionDiagnostic)] -#[error(ast_passes::c_var_args_is_sole_param)] -pub struct CVarArgsIsSoleParam { +#[error(ast_passes::fn_param_c_var_args_only)] +pub struct FnParamCVarArgsOnly { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(ast_passes::c_var_args_not_last)] -pub struct CVarArgsNotLast { +#[error(ast_passes::fn_param_c_var_args_not_last)] +pub struct FnParamCVarArgsNotLast { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(ast_passes::doc_comment_on_fn_param)] -pub struct DocCommentOnFnParam { +#[error(ast_passes::fn_param_doc_comment)] +pub struct FnParamDocComment { #[primary_span] #[label] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(ast_passes::forbidden_attr_on_fn_param)] -pub struct ForbiddenAttrOnFnParam { +#[error(ast_passes::fn_param_forbidden_attr)] +pub struct FnParamForbiddenAttr { #[primary_span] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[error(ast_passes::fn_param_forbidden_self)] +#[note] +pub struct FnParamForbiddenSelf { + #[primary_span] + #[label] + pub span: Span, +} diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl index 49ef0cc83de3d..77826f639f4dc 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -38,18 +38,23 @@ ast_passes_forbidden_lifetime_bound = ast_passes_forbidden_non_lifetime_param = only lifetime parameters can be used in this context -ast_passes_too_many_params = +ast_passes_fn_param_too_many = function can not have more than {$max_num_args} arguments -ast_passes_c_var_args_is_sole_param = +ast_passes_fn_param_c_var_args_only = C-variadic function must be declared with at least one named argument -ast_passes_c_var_args_not_last = +ast_passes_fn_param_c_var_args_not_last = `...` must be the last argument of a C-variadic function -ast_passes_doc_comment_on_fn_param = +ast_passes_fn_param_doc_comment = documentation comments cannot be applied to function parameters .label = doc comments are not allowed here -ast_passes_forbidden_attr_on_fn_param = +ast_passes_fn_param_forbidden_attr = allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + +ast_passes_fn_param_forbidden_self = + `self` parameter is only allowed in associated functions + .label = not semantically valid as function parameter + .note = associated functions are those in `impl` or `trait` definitions From b28cc097cfbdc9e2f105a7e644389266027bcf7d Mon Sep 17 00:00:00 2001 From: finalchild Date: Thu, 18 Aug 2022 21:20:50 +0900 Subject: [PATCH 18/23] Support #[fatal(..)] --- compiler/rustc_ast_passes/src/ast_validation.rs | 2 +- compiler/rustc_ast_passes/src/errors.rs | 2 +- compiler/rustc_session/src/parse.rs | 16 ++++++++++++++++ compiler/rustc_session/src/session.rs | 9 +++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 1c3a4ab7c6764..c8b46dde1c741 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -331,7 +331,7 @@ impl<'a> AstValidator<'a> { let max_num_args: usize = u16::MAX.into(); if fn_decl.inputs.len() > max_num_args { let Param { span, .. } = fn_decl.inputs[0]; - self.session.emit_err(FnParamTooMany { span, max_num_args }); + self.session.emit_fatal(FnParamTooMany { span, max_num_args }); } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index ee375f1ced7e0..0287d71feb33e 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -106,7 +106,7 @@ pub struct ForbiddenNonLifetimeParam { } #[derive(SessionDiagnostic)] -#[error(ast_passes::fn_param_too_many)] +#[fatal(ast_passes::fn_param_too_many)] pub struct FnParamTooMany { #[primary_span] pub span: Span, diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index b9b2356130a59..17866dc6bddcb 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -360,6 +360,17 @@ impl ParseSess { self.create_warning(warning).emit() } + pub fn create_fatal<'a>( + &'a self, + fatal: impl SessionDiagnostic<'a, !>, + ) -> DiagnosticBuilder<'a, !> { + fatal.into_diagnostic(self) + } + + pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! { + self.create_fatal(fatal).emit() + } + #[rustc_lint_diagnostics] pub fn struct_err( &self, @@ -373,6 +384,11 @@ impl ParseSess { self.span_diagnostic.struct_warn(msg) } + #[rustc_lint_diagnostics] + pub fn struct_fatal(&self, msg: impl Into) -> DiagnosticBuilder<'_, !> { + self.span_diagnostic.struct_fatal(msg) + } + #[rustc_lint_diagnostics] pub fn struct_diagnostic( &self, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 80de451276c2c..255d919eb1452 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -482,6 +482,15 @@ impl Session { pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) { self.parse_sess.emit_warning(warning) } + pub fn create_fatal<'a>( + &'a self, + fatal: impl SessionDiagnostic<'a, !>, + ) -> DiagnosticBuilder<'a, !> { + self.parse_sess.create_fatal(fatal) + } + pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) { + self.parse_sess.emit_fatal(fatal) + } #[inline] pub fn err_count(&self) -> usize { self.diagnostic().err_count() From 8ed8aac3caa9c943e600392e49702c7215428d23 Mon Sep 17 00:00:00 2001 From: finalchild Date: Fri, 19 Aug 2022 02:21:35 +0900 Subject: [PATCH 19/23] Fix `build_format` not unescaping braces properly Co-authored-by: RanolP --- .../rustc_macros/src/diagnostics/utils.rs | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 002abb152f759..ad9ecd39b9e85 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -235,35 +235,40 @@ pub(crate) trait HasFieldMap { // the referenced fields. Leaves `it` sitting on the closing brace of the format string, so // the next call to `it.next()` retrieves the next character. while let Some(c) = it.next() { - if c == '{' && *it.peek().unwrap_or(&'\0') != '{' { - let mut eat_argument = || -> Option { - let mut result = String::new(); - // Format specifiers look like: - // - // format := '{' [ argument ] [ ':' format_spec ] '}' . - // - // Therefore, we only need to eat until ':' or '}' to find the argument. - while let Some(c) = it.next() { - result.push(c); - let next = *it.peek().unwrap_or(&'\0'); - if next == '}' { - break; - } else if next == ':' { - // Eat the ':' character. - assert_eq!(it.next().unwrap(), ':'); - break; - } - } - // Eat until (and including) the matching '}' - while it.next()? != '}' { - continue; + if c != '{' { + continue; + } + if *it.peek().unwrap_or(&'\0') == '{' { + assert_eq!(it.next().unwrap(), '{'); + continue; + } + let mut eat_argument = || -> Option { + let mut result = String::new(); + // Format specifiers look like: + // + // format := '{' [ argument ] [ ':' format_spec ] '}' . + // + // Therefore, we only need to eat until ':' or '}' to find the argument. + while let Some(c) = it.next() { + result.push(c); + let next = *it.peek().unwrap_or(&'\0'); + if next == '}' { + break; + } else if next == ':' { + // Eat the ':' character. + assert_eq!(it.next().unwrap(), ':'); + break; } - Some(result) - }; - - if let Some(referenced_field) = eat_argument() { - referenced_fields.insert(referenced_field); } + // Eat until (and including) the matching '}' + while it.next()? != '}' { + continue; + } + Some(result) + }; + + if let Some(referenced_field) = eat_argument() { + referenced_fields.insert(referenced_field); } } From e331ae57df08e6eab346a9caab3fc354ce61c5d5 Mon Sep 17 00:00:00 2001 From: finalchild Date: Fri, 19 Aug 2022 02:43:01 +0900 Subject: [PATCH 20/23] Migrate forbidden_default and *_without_body --- .../rustc_ast_passes/src/ast_validation.rs | 128 ++++++++---------- compiler/rustc_ast_passes/src/errors.rs | 100 +++++++++++++- .../locales/en-US/ast_passes.ftl | 33 +++++ 3 files changed, 185 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index c8b46dde1c741..b337e5328c5df 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -13,7 +13,7 @@ use rustc_ast::walk_list; use rustc_ast::*; use rustc_ast_pretty::pprust::{self, State}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability, Diagnostic}; +use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability}; use rustc_parse::validate_attr; use rustc_session::lint::builtin::{ DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY, @@ -390,47 +390,20 @@ impl<'a> AstValidator<'a> { fn check_defaultness(&self, span: Span, defaultness: Defaultness) { if let Defaultness::Default(def_span) = defaultness { let span = self.session.source_map().guess_head_span(span); - self.err_handler() - .struct_span_err(span, "`default` is only allowed on items in trait impls") - .span_label(def_span, "`default` because of this") - .emit(); + self.session.emit_err(ForbiddenDefault { span, def_span }); } } - fn error_item_without_body(&self, sp: Span, ctx: &str, msg: &str, sugg: &str) { - self.error_item_without_body_with_help(sp, ctx, msg, sugg, |_| ()); - } - - fn error_item_without_body_with_help( - &self, - sp: Span, - ctx: &str, - msg: &str, - sugg: &str, - help: impl FnOnce(&mut Diagnostic), - ) { + /// If `sp` ends with a semicolon, returns it as a `Span` + /// Otherwise, returns `sp.shrink_to_hi()` + fn ending_semi_or_hi(&self, sp: Span) -> Span { let source_map = self.session.source_map(); let end = source_map.end_point(sp); - let replace_span = if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) { + + if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) { end } else { sp.shrink_to_hi() - }; - let mut err = self.err_handler().struct_span_err(sp, msg); - err.span_suggestion( - replace_span, - &format!("provide a definition for the {}", ctx), - sugg, - Applicability::HasPlaceholders, - ); - help(&mut err); - err.emit(); - } - - fn check_impl_item_provided(&self, sp: Span, body: &Option, ctx: &str, sugg: &str) { - if body.is_none() { - let msg = format!("associated {} in `impl` without body", ctx); - self.error_item_without_body(sp, ctx, &msg, sugg); } } @@ -1123,37 +1096,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_defaultness(item.span, defaultness); if body.is_none() { - let msg = "free function without a body"; - let ext = sig.header.ext; - - let f = |e: &mut Diagnostic| { - if let Extern::Implicit(start_span) | Extern::Explicit(_, start_span) = &ext - { - let start_suggestion = if let Extern::Explicit(abi, _) = ext { - format!("extern \"{}\" {{", abi.symbol_unescaped) - } else { - "extern {".to_owned() - }; - - let end_suggestion = " }".to_owned(); - let end_span = item.span.shrink_to_hi(); - - e - .multipart_suggestion( - "if you meant to declare an externally defined function, use an `extern` block", - vec![(*start_span, start_suggestion), (end_span, end_suggestion)], - Applicability::MaybeIncorrect, - ); - } - }; - - self.error_item_without_body_with_help( - item.span, - "function", - msg, - " { }", - f, - ); + self.session.emit_err(FnWithoutBody { + span: item.span, + replace_span: self.ending_semi_or_hi(item.span), + extern_block_suggestion: match sig.header.ext { + Extern::None => None, + Extern::Implicit(start_span) => Some(ExternBlockSuggestion { + start_span, + end_span: item.span.shrink_to_hi(), + abi: None, + }), + Extern::Explicit(abi, start_span) => Some(ExternBlockSuggestion { + start_span, + end_span: item.span.shrink_to_hi(), + abi: Some(abi.symbol_unescaped), + }), + }, + }); } self.visit_vis(&item.vis); @@ -1259,12 +1218,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ItemKind::Const(def, .., None) => { self.check_defaultness(item.span, def); - let msg = "free constant item without body"; - self.error_item_without_body(item.span, "constant", msg, " = ;"); + self.session.emit_err(ConstWithoutBody { + span: item.span, + replace_span: self.ending_semi_or_hi(item.span), + }); } ItemKind::Static(.., None) => { - let msg = "free static item without body"; - self.error_item_without_body(item.span, "static", msg, " = ;"); + self.session.emit_err(StaticWithoutBody { + span: item.span, + replace_span: self.ending_semi_or_hi(item.span), + }); } ItemKind::TyAlias(box TyAlias { defaultness, @@ -1275,8 +1238,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }) => { self.check_defaultness(item.span, defaultness); if ty.is_none() { - let msg = "free type alias without body"; - self.error_item_without_body(item.span, "type", msg, " = ;"); + self.session.emit_err(TyAliasWithoutBody { + span: item.span, + replace_span: self.ending_semi_or_hi(item.span), + }); } self.check_type_no_bounds(bounds, "this context"); if where_clauses.1.0 { @@ -1580,10 +1545,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if ctxt == AssocCtxt::Impl { match &item.kind { AssocItemKind::Const(_, _, body) => { - self.check_impl_item_provided(item.span, body, "constant", " = ;"); + if body.is_none() { + self.session.emit_err(AssocConstWithoutBody { + span: item.span, + replace_span: self.ending_semi_or_hi(item.span), + }); + } } AssocItemKind::Fn(box Fn { body, .. }) => { - self.check_impl_item_provided(item.span, body, "function", " { }"); + if body.is_none() { + self.session.emit_err(AssocFnWithoutBody { + span: item.span, + replace_span: self.ending_semi_or_hi(item.span), + }); + } } AssocItemKind::TyAlias(box TyAlias { generics, @@ -1593,7 +1568,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ty, .. }) => { - self.check_impl_item_provided(item.span, ty, "type", " = ;"); + if ty.is_none() { + self.session.emit_err(AssocTypeWithoutBody { + span: item.span, + replace_span: self.ending_semi_or_hi(item.span), + }); + } self.check_type_no_bounds(bounds, "`impl`s"); if ty.is_some() { self.check_gat_where( diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 0287d71feb33e..1ac4dac10e2b3 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -1,7 +1,6 @@ //! Errors emitted by ast_passes. -use rustc_errors::fluent; -use rustc_errors::{AddSubdiagnostic, Diagnostic}; +use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::{Span, Symbol}; @@ -150,3 +149,100 @@ pub struct FnParamForbiddenSelf { #[label] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[error(ast_passes::forbidden_default)] +pub struct ForbiddenDefault { + #[primary_span] + pub span: Span, + #[label] + pub def_span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::assoc_const_without_body)] +pub struct AssocConstWithoutBody { + #[primary_span] + pub span: Span, + #[suggestion(code = " = ;", applicability = "has-placeholders")] + pub replace_span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::assoc_fn_without_body)] +pub struct AssocFnWithoutBody { + #[primary_span] + pub span: Span, + #[suggestion(code = " {{ }}", applicability = "has-placeholders")] + pub replace_span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::assoc_type_without_body)] +pub struct AssocTypeWithoutBody { + #[primary_span] + pub span: Span, + #[suggestion(code = " = ;", applicability = "has-placeholders")] + pub replace_span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::const_without_body)] +pub struct ConstWithoutBody { + #[primary_span] + pub span: Span, + #[suggestion(code = " = ;", applicability = "has-placeholders")] + pub replace_span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::static_without_body)] +pub struct StaticWithoutBody { + #[primary_span] + pub span: Span, + #[suggestion(code = " = ;", applicability = "has-placeholders")] + pub replace_span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::ty_alias_without_body)] +pub struct TyAliasWithoutBody { + #[primary_span] + pub span: Span, + #[suggestion(code = " = ;", applicability = "has-placeholders")] + pub replace_span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(ast_passes::fn_without_body)] +pub struct FnWithoutBody { + #[primary_span] + pub span: Span, + #[suggestion(code = " {{ }}", applicability = "has-placeholders")] + pub replace_span: Span, + #[subdiagnostic] + pub extern_block_suggestion: Option, +} + +pub struct ExternBlockSuggestion { + pub start_span: Span, + pub end_span: Span, + pub abi: Option, +} + +impl AddSubdiagnostic for ExternBlockSuggestion { + fn add_to_diagnostic(self, diag: &mut Diagnostic) { + let start_suggestion = if let Some(abi) = self.abi { + format!("extern \"{}\" {{", abi) + } else { + "extern {".to_owned() + }; + let end_suggestion = " }".to_owned(); + + diag.multipart_suggestion( + fluent::ast_passes::extern_block_suggestion, + vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)], + Applicability::MaybeIncorrect, + ); + } +} diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl index 77826f639f4dc..db91a886c725e 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -58,3 +58,36 @@ ast_passes_fn_param_forbidden_self = `self` parameter is only allowed in associated functions .label = not semantically valid as function parameter .note = associated functions are those in `impl` or `trait` definitions + +ast_passes_forbidden_default = + `default` is only allowed on items in trait impls + .label = `default` because of this + +ast_passes_assoc_const_without_body = + associated constant in `impl` without body + .suggestion = provide a definition for the constant + +ast_passes_assoc_fn_without_body = + associated function in `impl` without body + .suggestion = provide a definition for the function + +ast_passes_assoc_type_without_body = + associated type in `impl` without body + .suggestion = provide a definition for the type + +ast_passes_const_without_body = + free constant item without body + .suggestion = provide a definition for the constant + +ast_passes_static_without_body = + free static item without body + .suggestion = provide a definition for the static + +ast_passes_ty_alias_without_body = + free type alias without body + .suggestion = provide a definition for the type + +ast_passes_fn_without_body = + free function without a body + .suggestion = provide a definition for the function + .extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block From 6a340741bde70856ece1cd99f61698e816436767 Mon Sep 17 00:00:00 2001 From: finalchild Date: Fri, 19 Aug 2022 03:36:43 +0900 Subject: [PATCH 21/23] Remove redundant clone --- compiler/rustc_builtin_macros/src/format.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index e76f5711b7b63..fd517c1e12136 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -1176,7 +1176,7 @@ fn create_lints_for_named_arguments_used_positionally(cx: &mut Context<'_, '_>) cx.ecx.buffered_early_lint.push(BufferedEarlyLint { span: MultiSpan::from_span(named_arg.positional_named_arg_span), - msg: msg.clone().into(), + msg: msg.into(), node_id: ast::CRATE_NODE_ID, lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY), diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally { From 70e0af632d0e3903616693dbe834da752ba26d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Park=20Jaeon=20=5B=ED=8C=8C=EC=B0=A8=5D?= Date: Sun, 21 Aug 2022 02:22:05 +0900 Subject: [PATCH 22/23] Fix incorrect return type of emit_fatal Co-authored-by: Giacomo Stevanato --- compiler/rustc_session/src/session.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 255d919eb1452..4972ae2014d50 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -488,7 +488,7 @@ impl Session { ) -> DiagnosticBuilder<'a, !> { self.parse_sess.create_fatal(fatal) } - pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) { + pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! { self.parse_sess.emit_fatal(fatal) } #[inline] From 09d495cc15e3ef3e80fc36f0c217c08c5bfb34de Mon Sep 17 00:00:00 2001 From: finalchild Date: Mon, 22 Aug 2022 01:24:47 +0900 Subject: [PATCH 23/23] Replace #[error(..)] etc. to #[diag(..)] --- compiler/rustc_ast_passes/src/errors.rs | 46 ++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 1ac4dac10e2b3..16ba14e909216 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -7,7 +7,7 @@ use rustc_span::{Span, Symbol}; use crate::ast_validation::ForbiddenLetReason; #[derive(SessionDiagnostic)] -#[error(ast_passes::forbidden_let)] +#[diag(ast_passes::forbidden_let)] #[note] pub struct ForbiddenLet { #[primary_span] @@ -31,21 +31,21 @@ impl AddSubdiagnostic for ForbiddenLetReason { } #[derive(SessionDiagnostic)] -#[error(ast_passes::forbidden_assoc_constraint)] +#[diag(ast_passes::forbidden_assoc_constraint)] pub struct ForbiddenAssocConstraint { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(ast_passes::keyword_lifetime)] +#[diag(ast_passes::keyword_lifetime)] pub struct KeywordLifetime { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(ast_passes::invalid_label)] +#[diag(ast_passes::invalid_label)] pub struct InvalidLabel { #[primary_span] pub span: Span, @@ -53,7 +53,7 @@ pub struct InvalidLabel { } #[derive(SessionDiagnostic)] -#[error(ast_passes::invalid_visibility, code = "E0449")] +#[diag(ast_passes::invalid_visibility, code = "E0449")] pub struct InvalidVisibility { #[primary_span] pub span: Span, @@ -72,7 +72,7 @@ pub enum InvalidVisibilityNote { } #[derive(SessionDiagnostic)] -#[error(ast_passes::trait_fn_async, code = "E0706")] +#[diag(ast_passes::trait_fn_async, code = "E0706")] #[note] #[note(ast_passes::note2)] pub struct TraitFnAsync { @@ -83,7 +83,7 @@ pub struct TraitFnAsync { } #[derive(SessionDiagnostic)] -#[error(ast_passes::trait_fn_const, code = "E0379")] +#[diag(ast_passes::trait_fn_const, code = "E0379")] pub struct TraitFnConst { #[primary_span] #[label] @@ -91,21 +91,21 @@ pub struct TraitFnConst { } #[derive(SessionDiagnostic)] -#[error(ast_passes::forbidden_lifetime_bound)] +#[diag(ast_passes::forbidden_lifetime_bound)] pub struct ForbiddenLifetimeBound { #[primary_span] pub spans: Vec, } #[derive(SessionDiagnostic)] -#[error(ast_passes::forbidden_non_lifetime_param)] +#[diag(ast_passes::forbidden_non_lifetime_param)] pub struct ForbiddenNonLifetimeParam { #[primary_span] pub spans: Vec, } #[derive(SessionDiagnostic)] -#[fatal(ast_passes::fn_param_too_many)] +#[diag(ast_passes::fn_param_too_many)] pub struct FnParamTooMany { #[primary_span] pub span: Span, @@ -113,21 +113,21 @@ pub struct FnParamTooMany { } #[derive(SessionDiagnostic)] -#[error(ast_passes::fn_param_c_var_args_only)] +#[diag(ast_passes::fn_param_c_var_args_only)] pub struct FnParamCVarArgsOnly { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(ast_passes::fn_param_c_var_args_not_last)] +#[diag(ast_passes::fn_param_c_var_args_not_last)] pub struct FnParamCVarArgsNotLast { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(ast_passes::fn_param_doc_comment)] +#[diag(ast_passes::fn_param_doc_comment)] pub struct FnParamDocComment { #[primary_span] #[label] @@ -135,14 +135,14 @@ pub struct FnParamDocComment { } #[derive(SessionDiagnostic)] -#[error(ast_passes::fn_param_forbidden_attr)] +#[diag(ast_passes::fn_param_forbidden_attr)] pub struct FnParamForbiddenAttr { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(ast_passes::fn_param_forbidden_self)] +#[diag(ast_passes::fn_param_forbidden_self)] #[note] pub struct FnParamForbiddenSelf { #[primary_span] @@ -151,7 +151,7 @@ pub struct FnParamForbiddenSelf { } #[derive(SessionDiagnostic)] -#[error(ast_passes::forbidden_default)] +#[diag(ast_passes::forbidden_default)] pub struct ForbiddenDefault { #[primary_span] pub span: Span, @@ -160,7 +160,7 @@ pub struct ForbiddenDefault { } #[derive(SessionDiagnostic)] -#[error(ast_passes::assoc_const_without_body)] +#[diag(ast_passes::assoc_const_without_body)] pub struct AssocConstWithoutBody { #[primary_span] pub span: Span, @@ -169,7 +169,7 @@ pub struct AssocConstWithoutBody { } #[derive(SessionDiagnostic)] -#[error(ast_passes::assoc_fn_without_body)] +#[diag(ast_passes::assoc_fn_without_body)] pub struct AssocFnWithoutBody { #[primary_span] pub span: Span, @@ -178,7 +178,7 @@ pub struct AssocFnWithoutBody { } #[derive(SessionDiagnostic)] -#[error(ast_passes::assoc_type_without_body)] +#[diag(ast_passes::assoc_type_without_body)] pub struct AssocTypeWithoutBody { #[primary_span] pub span: Span, @@ -187,7 +187,7 @@ pub struct AssocTypeWithoutBody { } #[derive(SessionDiagnostic)] -#[error(ast_passes::const_without_body)] +#[diag(ast_passes::const_without_body)] pub struct ConstWithoutBody { #[primary_span] pub span: Span, @@ -196,7 +196,7 @@ pub struct ConstWithoutBody { } #[derive(SessionDiagnostic)] -#[error(ast_passes::static_without_body)] +#[diag(ast_passes::static_without_body)] pub struct StaticWithoutBody { #[primary_span] pub span: Span, @@ -205,7 +205,7 @@ pub struct StaticWithoutBody { } #[derive(SessionDiagnostic)] -#[error(ast_passes::ty_alias_without_body)] +#[diag(ast_passes::ty_alias_without_body)] pub struct TyAliasWithoutBody { #[primary_span] pub span: Span, @@ -214,7 +214,7 @@ pub struct TyAliasWithoutBody { } #[derive(SessionDiagnostic)] -#[error(ast_passes::fn_without_body)] +#[diag(ast_passes::fn_without_body)] pub struct FnWithoutBody { #[primary_span] pub span: Span,