Improve diagnostics for const a: = expr;
This commit is contained in:
parent
1f5d8d49eb
commit
743ad07c4b
@ -1179,10 +1179,11 @@ fn parse_item_global(
|
||||
|
||||
// Parse the type of a `const` or `static mut?` item.
|
||||
// That is, the `":" $ty` fragment.
|
||||
let ty = if self.eat(&token::Colon) {
|
||||
self.parse_ty()?
|
||||
} else {
|
||||
self.recover_missing_const_type(id, m)
|
||||
let ty = match (self.eat(&token::Colon), self.check(&token::Eq) | self.check(&token::Semi))
|
||||
{
|
||||
// If there wasn't a `:` or the colon was followed by a `=` or `;` recover a missing type.
|
||||
(true, false) => self.parse_ty()?,
|
||||
(colon, _) => self.recover_missing_const_type(colon, m),
|
||||
};
|
||||
|
||||
let expr = if self.eat(&token::Eq) { Some(self.parse_expr()?) } else { None };
|
||||
@ -1190,9 +1191,9 @@ fn parse_item_global(
|
||||
Ok((id, ty, expr))
|
||||
}
|
||||
|
||||
/// We were supposed to parse `:` but the `:` was missing.
|
||||
/// We were supposed to parse `":" $ty` but the `:` or the type was missing.
|
||||
/// This means that the type is missing.
|
||||
fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
|
||||
fn recover_missing_const_type(&mut self, colon_present: bool, m: Option<Mutability>) -> P<Ty> {
|
||||
// Construct the error and stash it away with the hope
|
||||
// that typeck will later enrich the error with a type.
|
||||
let kind = match m {
|
||||
@ -1200,18 +1201,25 @@ fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<
|
||||
Some(Mutability::Not) => "static",
|
||||
None => "const",
|
||||
};
|
||||
let mut err = self.struct_span_err(id.span, &format!("missing type for `{kind}` item"));
|
||||
|
||||
let colon = match colon_present {
|
||||
true => "",
|
||||
false => ":",
|
||||
};
|
||||
|
||||
let span = self.prev_token.span.shrink_to_hi();
|
||||
let mut err = self.struct_span_err(span, &format!("missing type for `{kind}` item"));
|
||||
err.span_suggestion(
|
||||
id.span,
|
||||
span,
|
||||
"provide a type for the item",
|
||||
format!("{id}: <type>"),
|
||||
format!("{colon} <type>"),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
err.stash(id.span, StashKey::ItemNoType);
|
||||
err.stash(span, StashKey::ItemNoType);
|
||||
|
||||
// The user intended that the type be inferred,
|
||||
// so treat this as if the user wrote e.g. `const A: _ = expr;`.
|
||||
P(Ty { kind: TyKind::Infer, span: id.span, id: ast::DUMMY_NODE_ID, tokens: None })
|
||||
P(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
|
||||
}
|
||||
|
||||
/// Parses an enum declaration.
|
||||
|
@ -801,6 +801,9 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match tcx.sess.diagnostic().steal_diagnostic(span, StashKey::ItemNoType) {
|
||||
Some(mut err) => {
|
||||
if !ty.references_error() {
|
||||
// Only suggest adding `:` if it was missing (and suggested by parsing diagnostic)
|
||||
let colon = if span == item_ident.span.shrink_to_hi() { ":" } else { "" };
|
||||
|
||||
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
|
||||
// We are typeck and have the real type, so remove that and suggest the actual type.
|
||||
// FIXME(eddyb) this looks like it should be functionality on `Diagnostic`.
|
||||
@ -816,7 +819,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!("provide a type for the {item}", item = kind),
|
||||
format!("{}: {}", item_ident, sugg_ty),
|
||||
format!("{colon} {sugg_ty}"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
|
@ -34,10 +34,10 @@ LL | #![a={impl std::ops::Neg for i8 {}}]
|
||||
| ^ consider adding a `main` function to `$DIR/issue-90873.rs`
|
||||
|
||||
error: missing type for `static` item
|
||||
--> $DIR/issue-90873.rs:1:16
|
||||
--> $DIR/issue-90873.rs:1:17
|
||||
|
|
||||
LL | #![u=||{static d=||1;}]
|
||||
| ^ help: provide a type for the item: `d: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -17,10 +17,10 @@ LL | | }
|
||||
= note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:19
|
||||
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:20
|
||||
|
|
||||
LL | const A = "A".$fn();
|
||||
| ^ help: provide a type for the constant: `A: usize`
|
||||
| ^ help: provide a type for the constant: `: usize`
|
||||
...
|
||||
LL | / suite! {
|
||||
LL | | len;
|
||||
@ -31,13 +31,13 @@ LL | | }
|
||||
= note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
|
||||
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:19
|
||||
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:20
|
||||
|
|
||||
LL | const A = "A".$fn();
|
||||
| ^
|
||||
| |
|
||||
| not allowed in type signatures
|
||||
| help: replace with the correct type: `bool`
|
||||
| ^
|
||||
| |
|
||||
| not allowed in type signatures
|
||||
| help: replace with the correct type: `bool`
|
||||
...
|
||||
LL | / suite! {
|
||||
LL | | len;
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: missing type for `const` item
|
||||
--> $DIR/issue-89574.rs:2:11
|
||||
--> $DIR/issue-89574.rs:2:22
|
||||
|
|
||||
LL | const EMPTY_ARRAY = [];
|
||||
| ^^^^^^^^^^^ help: provide a type for the item: `EMPTY_ARRAY: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -15,10 +15,10 @@ LL | const B;
|
||||
| help: provide a definition for the constant: `= <expr>;`
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/item-free-const-no-body-semantic-fail.rs:6:7
|
||||
--> $DIR/item-free-const-no-body-semantic-fail.rs:6:8
|
||||
|
|
||||
LL | const B;
|
||||
| ^ help: provide a type for the item: `B: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -31,16 +31,16 @@ LL | static mut D;
|
||||
| help: provide a definition for the static: `= <expr>;`
|
||||
|
||||
error: missing type for `static` item
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:6:8
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:6:9
|
||||
|
|
||||
LL | static B;
|
||||
| ^ help: provide a type for the item: `B: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: missing type for `static mut` item
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:10:12
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:10:13
|
||||
|
|
||||
LL | static mut D;
|
||||
| ^ help: provide a type for the item: `D: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -16,10 +16,10 @@ LL | }
|
||||
| - the item list ends here
|
||||
|
||||
error: missing type for `static` item
|
||||
--> $DIR/removed-syntax-static-fn.rs:4:12
|
||||
--> $DIR/removed-syntax-static-fn.rs:4:14
|
||||
|
|
||||
LL | static fn f() {}
|
||||
| ^^ help: provide a type for the item: `r#fn: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -14,38 +14,38 @@ fn main() {}
|
||||
const C2 = 42;
|
||||
//~^ ERROR missing type for `const` item
|
||||
//~| HELP provide a type for the item
|
||||
//~| SUGGESTION C2: <type>
|
||||
//~| SUGGESTION : <type>
|
||||
|
||||
#[cfg(FALSE)]
|
||||
static S2 = "abc";
|
||||
//~^ ERROR missing type for `static` item
|
||||
//~| HELP provide a type for the item
|
||||
//~| SUGGESTION S2: <type>
|
||||
//~| SUGGESTION : <type>
|
||||
|
||||
#[cfg(FALSE)]
|
||||
static mut SM2 = "abc";
|
||||
//~^ ERROR missing type for `static mut` item
|
||||
//~| HELP provide a type for the item
|
||||
//~| SUGGESTION SM2: <type>
|
||||
//~| SUGGESTION : <type>
|
||||
|
||||
// These will, so the diagnostics should be stolen by typeck:
|
||||
|
||||
const C = 42;
|
||||
//~^ ERROR missing type for `const` item
|
||||
//~| HELP provide a type for the constant
|
||||
//~| SUGGESTION C: i32
|
||||
//~| SUGGESTION : i32
|
||||
|
||||
const D = &&42;
|
||||
//~^ ERROR missing type for `const` item
|
||||
//~| HELP provide a type for the constant
|
||||
//~| SUGGESTION D: &&i32
|
||||
//~| SUGGESTION : &&i32
|
||||
|
||||
static S = Vec::<String>::new();
|
||||
//~^ ERROR missing type for `static` item
|
||||
//~| HELP provide a type for the static variable
|
||||
//~| SUGGESTION S: Vec<String>
|
||||
//~| SUGGESTION : Vec<String>
|
||||
|
||||
static mut SM = "abc";
|
||||
//~^ ERROR missing type for `static mut` item
|
||||
//~| HELP provide a type for the static variable
|
||||
//~| SUGGESTION &str
|
||||
//~| SUGGESTION : &str
|
||||
|
@ -1,44 +1,44 @@
|
||||
error: missing type for `const` item
|
||||
--> $DIR/const-no-type.rs:33:7
|
||||
--> $DIR/const-no-type.rs:33:8
|
||||
|
|
||||
LL | const C = 42;
|
||||
| ^ help: provide a type for the constant: `C: i32`
|
||||
| ^ help: provide a type for the constant: `: i32`
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/const-no-type.rs:38:7
|
||||
--> $DIR/const-no-type.rs:38:8
|
||||
|
|
||||
LL | const D = &&42;
|
||||
| ^ help: provide a type for the constant: `D: &&i32`
|
||||
| ^ help: provide a type for the constant: `: &&i32`
|
||||
|
||||
error: missing type for `static` item
|
||||
--> $DIR/const-no-type.rs:43:8
|
||||
--> $DIR/const-no-type.rs:43:9
|
||||
|
|
||||
LL | static S = Vec::<String>::new();
|
||||
| ^ help: provide a type for the static variable: `S: Vec<String>`
|
||||
| ^ help: provide a type for the static variable: `: Vec<String>`
|
||||
|
||||
error: missing type for `static mut` item
|
||||
--> $DIR/const-no-type.rs:48:12
|
||||
--> $DIR/const-no-type.rs:48:14
|
||||
|
|
||||
LL | static mut SM = "abc";
|
||||
| ^^ help: provide a type for the static variable: `SM: &str`
|
||||
| ^ help: provide a type for the static variable: `: &str`
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/const-no-type.rs:14:7
|
||||
--> $DIR/const-no-type.rs:14:9
|
||||
|
|
||||
LL | const C2 = 42;
|
||||
| ^^ help: provide a type for the item: `C2: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: missing type for `static` item
|
||||
--> $DIR/const-no-type.rs:20:8
|
||||
--> $DIR/const-no-type.rs:20:10
|
||||
|
|
||||
LL | static S2 = "abc";
|
||||
| ^^ help: provide a type for the item: `S2: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: missing type for `static mut` item
|
||||
--> $DIR/const-no-type.rs:26:12
|
||||
--> $DIR/const-no-type.rs:26:15
|
||||
|
|
||||
LL | static mut SM2 = "abc";
|
||||
| ^^^ help: provide a type for the item: `SM2: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: missing type for `const` item
|
||||
--> $DIR/unnamable-types.rs:6:7
|
||||
--> $DIR/unnamable-types.rs:6:8
|
||||
|
|
||||
LL | const A = 5;
|
||||
| ^ help: provide a type for the constant: `A: i32`
|
||||
| ^ help: provide a type for the constant: `: i32`
|
||||
|
||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
|
||||
--> $DIR/unnamable-types.rs:10:11
|
||||
@ -26,10 +26,10 @@ LL | const C: _ = || 42;
|
||||
| ^^^^^
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/unnamable-types.rs:23:7
|
||||
--> $DIR/unnamable-types.rs:23:8
|
||||
|
|
||||
LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
|
||||
| ^
|
||||
| ^
|
||||
|
|
||||
note: however, the inferred type `S<[closure@$DIR/unnamable-types.rs:23:31: 23:45]>` cannot be named
|
||||
--> $DIR/unnamable-types.rs:23:11
|
||||
@ -38,22 +38,22 @@ LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/unnamable-types.rs:29:7
|
||||
--> $DIR/unnamable-types.rs:29:8
|
||||
|
|
||||
LL | const E = foo;
|
||||
| ^ help: provide a type for the constant: `E: fn() -> i32`
|
||||
| ^ help: provide a type for the constant: `: fn() -> i32`
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/unnamable-types.rs:32:7
|
||||
--> $DIR/unnamable-types.rs:32:8
|
||||
|
|
||||
LL | const F = S { t: foo };
|
||||
| ^ help: provide a type for the constant: `F: S<fn() -> i32>`
|
||||
| ^ help: provide a type for the constant: `: S<fn() -> i32>`
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/unnamable-types.rs:37:7
|
||||
--> $DIR/unnamable-types.rs:37:8
|
||||
|
|
||||
LL | const G = || -> i32 { yield 0; return 1; };
|
||||
| ^
|
||||
| ^
|
||||
|
|
||||
note: however, the inferred type `[generator@$DIR/unnamable-types.rs:37:11: 37:20]` cannot be named
|
||||
--> $DIR/unnamable-types.rs:37:11
|
||||
|
9
src/test/ui/typeck/issue-100164.fixed
Normal file
9
src/test/ui/typeck/issue-100164.fixed
Normal file
@ -0,0 +1,9 @@
|
||||
// run-rustfix
|
||||
|
||||
const _A: i32 = 123;
|
||||
//~^ ERROR: missing type for `const` item
|
||||
|
||||
fn main() {
|
||||
const _B: i32 = 123;
|
||||
//~^ ERROR: missing type for `const` item
|
||||
}
|
9
src/test/ui/typeck/issue-100164.rs
Normal file
9
src/test/ui/typeck/issue-100164.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// run-rustfix
|
||||
|
||||
const _A: = 123;
|
||||
//~^ ERROR: missing type for `const` item
|
||||
|
||||
fn main() {
|
||||
const _B: = 123;
|
||||
//~^ ERROR: missing type for `const` item
|
||||
}
|
14
src/test/ui/typeck/issue-100164.stderr
Normal file
14
src/test/ui/typeck/issue-100164.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: missing type for `const` item
|
||||
--> $DIR/issue-100164.rs:3:10
|
||||
|
|
||||
LL | const _A: = 123;
|
||||
| ^ help: provide a type for the constant: `i32`
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/issue-100164.rs:7:14
|
||||
|
|
||||
LL | const _B: = 123;
|
||||
| ^ help: provide a type for the constant: `i32`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -7,10 +7,10 @@ LL | const FOO = "hello" + 1;
|
||||
| &str
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/issue-79040.rs:2:11
|
||||
--> $DIR/issue-79040.rs:2:14
|
||||
|
|
||||
LL | const FOO = "hello" + 1;
|
||||
| ^^^ help: provide a type for the item: `FOO: <type>`
|
||||
| ^ help: provide a type for the item: `: <type>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -189,10 +189,10 @@ LL ~ b: (T, T),
|
||||
|
|
||||
|
||||
error: missing type for `static` item
|
||||
--> $DIR/typeck_type_placeholder_item.rs:73:12
|
||||
--> $DIR/typeck_type_placeholder_item.rs:73:13
|
||||
|
|
||||
LL | static A = 42;
|
||||
| ^ help: provide a type for the static variable: `A: i32`
|
||||
| ^ help: provide a type for the static variable: `: i32`
|
||||
|
||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
|
||||
--> $DIR/typeck_type_placeholder_item.rs:75:15
|
||||
|
Loading…
Reference in New Issue
Block a user