Do not suggest to add type annotations for unnameable types
This commit is contained in:
parent
66ba81059e
commit
f687d5c43a
@ -749,6 +749,17 @@ fn infer_placeholder_type(
|
|||||||
span: Span,
|
span: Span,
|
||||||
item_ident: Ident,
|
item_ident: Ident,
|
||||||
) -> Ty<'_> {
|
) -> Ty<'_> {
|
||||||
|
fn contains_anonymous(ty: Ty<'_>) -> bool {
|
||||||
|
for gen_arg in ty.walk() {
|
||||||
|
if let ty::subst::GenericArgKind::Type(inner_ty) = gen_arg.unpack() {
|
||||||
|
if let ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) = inner_ty.kind() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
let ty = tcx.diagnostic_only_typeck(def_id).node_type(body_id.hir_id);
|
let ty = tcx.diagnostic_only_typeck(def_id).node_type(body_id.hir_id);
|
||||||
|
|
||||||
// If this came from a free `const` or `static mut?` item,
|
// If this came from a free `const` or `static mut?` item,
|
||||||
@ -760,24 +771,41 @@ fn infer_placeholder_type(
|
|||||||
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
|
// 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.
|
// We are typeck and have the real type, so remove that and suggest the actual type.
|
||||||
err.suggestions.clear();
|
err.suggestions.clear();
|
||||||
err.span_suggestion(
|
|
||||||
span,
|
// Suggesting unnameable types won't help.
|
||||||
"provide a type for the item",
|
if !contains_anonymous(ty) {
|
||||||
format!("{}: {}", item_ident, ty),
|
err.span_suggestion(
|
||||||
Applicability::MachineApplicable,
|
span,
|
||||||
)
|
"provide a type for the item",
|
||||||
.emit_unless(ty.references_error());
|
format!("{}: {}", item_ident, ty),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
err.span_note(
|
||||||
|
tcx.hir().body(body_id).value.span,
|
||||||
|
&format!("however, the inferred type `{}` cannot be named", ty.to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
err.emit_unless(ty.references_error());
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut diag = bad_placeholder_type(tcx, vec![span]);
|
let mut diag = bad_placeholder_type(tcx, vec![span]);
|
||||||
|
|
||||||
if !ty.references_error() {
|
if !ty.references_error() {
|
||||||
diag.span_suggestion(
|
if !contains_anonymous(ty) {
|
||||||
span,
|
diag.span_suggestion(
|
||||||
"replace with the correct type",
|
span,
|
||||||
ty.to_string(),
|
"replace with the correct type",
|
||||||
Applicability::MaybeIncorrect,
|
ty.to_string(),
|
||||||
);
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
diag.span_note(
|
||||||
|
tcx.hir().body(body_id).value.span,
|
||||||
|
&format!("however, the inferred type `{}` cannot be named", ty.to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diag.emit();
|
diag.emit();
|
||||||
|
33
src/test/ui/suggestions/unnamable-types.rs
Normal file
33
src/test/ui/suggestions/unnamable-types.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Test that we do not suggest to add type annotations for unnamable types.
|
||||||
|
|
||||||
|
#![crate_type="lib"]
|
||||||
|
#![feature(generators)]
|
||||||
|
|
||||||
|
const A = 5;
|
||||||
|
//~^ ERROR: missing type for `const` item
|
||||||
|
//~| HELP: provide a type for the item
|
||||||
|
|
||||||
|
static B: _ = "abc";
|
||||||
|
//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
//~| NOTE: not allowed in type signatures
|
||||||
|
//~| HELP: replace with the correct type
|
||||||
|
|
||||||
|
|
||||||
|
const C: _ = || 42;
|
||||||
|
//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
//~| NOTE: not allowed in type signatures
|
||||||
|
//~| NOTE: however, the inferred type
|
||||||
|
|
||||||
|
struct S<T> { t: T }
|
||||||
|
const D = S { t: || -> i32 { 42 } };
|
||||||
|
//~^ ERROR: missing type for `const` item
|
||||||
|
//~| NOTE: however, the inferred type
|
||||||
|
|
||||||
|
fn foo() -> i32 { 42 }
|
||||||
|
const E = S { t: foo };
|
||||||
|
//~^ ERROR: missing type for `const` item
|
||||||
|
//~| NOTE: however, the inferred type
|
||||||
|
|
||||||
|
const F = || -> i32 { yield 0; return 1; };
|
||||||
|
//~^ ERROR: missing type for `const` item
|
||||||
|
//~| NOTE: however, the inferred type
|
66
src/test/ui/suggestions/unnamable-types.stderr
Normal file
66
src/test/ui/suggestions/unnamable-types.stderr
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
error: missing type for `const` item
|
||||||
|
--> $DIR/unnamable-types.rs:6:7
|
||||||
|
|
|
||||||
|
LL | const A = 5;
|
||||||
|
| ^ help: provide a type for the item: `A: i32`
|
||||||
|
|
||||||
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
--> $DIR/unnamable-types.rs:10:11
|
||||||
|
|
|
||||||
|
LL | static B: _ = "abc";
|
||||||
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace with the correct type: `&str`
|
||||||
|
|
||||||
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
--> $DIR/unnamable-types.rs:16:10
|
||||||
|
|
|
||||||
|
LL | const C: _ = || 42;
|
||||||
|
| ^ not allowed in type signatures
|
||||||
|
|
|
||||||
|
note: however, the inferred type `[closure@$DIR/unnamable-types.rs:16:14: 16:19]` cannot be named
|
||||||
|
--> $DIR/unnamable-types.rs:16:14
|
||||||
|
|
|
||||||
|
LL | const C: _ = || 42;
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: missing type for `const` item
|
||||||
|
--> $DIR/unnamable-types.rs:22:7
|
||||||
|
|
|
||||||
|
LL | const D = S { t: || -> i32 { 42 } };
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
note: however, the inferred type `S<[closure@$DIR/unnamable-types.rs:22:18: 22:34]>` cannot be named
|
||||||
|
--> $DIR/unnamable-types.rs:22:11
|
||||||
|
|
|
||||||
|
LL | const D = S { t: || -> i32 { 42 } };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: missing type for `const` item
|
||||||
|
--> $DIR/unnamable-types.rs:27:7
|
||||||
|
|
|
||||||
|
LL | const E = S { t: foo };
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
note: however, the inferred type `S<fn() -> i32 {foo}>` cannot be named
|
||||||
|
--> $DIR/unnamable-types.rs:27:11
|
||||||
|
|
|
||||||
|
LL | const E = S { t: foo };
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: missing type for `const` item
|
||||||
|
--> $DIR/unnamable-types.rs:31:7
|
||||||
|
|
|
||||||
|
LL | const F = || -> i32 { yield 0; return 1; };
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
note: however, the inferred type `[generator@$DIR/unnamable-types.rs:31:11: 31:43 {i32, ()}]` cannot be named
|
||||||
|
--> $DIR/unnamable-types.rs:31:11
|
||||||
|
|
|
||||||
|
LL | const F = || -> i32 { yield 0; return 1; };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0121`.
|
Loading…
x
Reference in New Issue
Block a user