Rollup merge of #95784 - WaffleLapkin:typeof_cool_suggestion, r=compiler-errors

Suggest replacing `typeof(...)` with an actual type

This PR adds suggestion to replace `typeof(...)` with an actual type of `...`, for example in case of `typeof(1)` we suggest replacing it with `i32`.

If the expression
1. Is not const (`{ let a = 1; let _: typeof(a); }`)
2. Can't be found (`let _: typeof(this_variable_does_not_exist)`)
3. Or has non-suggestable type (closure, generator, error, etc)
we don't suggest anything.

The 1 one is sad, but it's not clear how to support non-consts expressions for `typeof`.

_This PR is inspired by [this tweet]._

[this tweet]: https://twitter.com/compiler_errors/status/1511945354752638976
This commit is contained in:
Dylan DPC 2022-04-10 21:03:34 +02:00 committed by GitHub
commit 54597ba11f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 3 deletions

View file

@ -62,6 +62,7 @@ typeck-functional-record-update-on-non-struct =
typeck-typeof-reserved-keyword-used =
`typeof` is a reserved keyword but unimplemented
.suggestion = consider replacing `typeof(...)` with an actual type
.label = reserved keyword
typeck-return-stmt-outside-of-fn-body =

View file

@ -2460,8 +2460,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.normalize_ty(ast_ty.span, array_ty)
}
hir::TyKind::Typeof(ref e) => {
tcx.sess.emit_err(TypeofReservedKeywordUsed { span: ast_ty.span });
tcx.type_of(tcx.hir().local_def_id(e.hir_id))
let ty = tcx.type_of(tcx.hir().local_def_id(e.hir_id));
let span = ast_ty.span;
tcx.sess.emit_err(TypeofReservedKeywordUsed {
span,
ty,
opt_sugg: Some((span, Applicability::MachineApplicable))
.filter(|_| ty.is_suggestable()),
});
ty
}
hir::TyKind::Infer => {
// Infer also appears as the type of arguments or return

View file

@ -1,5 +1,7 @@
//! Errors emitted by typeck.
use rustc_errors::Applicability;
use rustc_macros::SessionDiagnostic;
use rustc_middle::ty::Ty;
use rustc_span::{symbol::Ident, Span, Symbol};
#[derive(SessionDiagnostic)]
@ -127,10 +129,13 @@ pub struct FunctionalRecordUpdateOnNonStruct {
#[derive(SessionDiagnostic)]
#[error(code = "E0516", slug = "typeck-typeof-reserved-keyword-used")]
pub struct TypeofReservedKeywordUsed {
pub struct TypeofReservedKeywordUsed<'tcx> {
pub ty: Ty<'tcx>,
#[primary_span]
#[label]
pub span: Span,
#[suggestion_verbose(message = "suggestion", code = "{ty}")]
pub opt_sugg: Option<(Span, Applicability)>,
}
#[derive(SessionDiagnostic)]

View file

@ -3,6 +3,11 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented
|
LL | let x: typeof(92) = 92;
| ^^^^^^^^^^ reserved keyword
|
help: consider replacing `typeof(...)` with an actual type
|
LL | let x: i32 = 92;
| ~~~
error: aborting due to previous error

View file

@ -3,6 +3,11 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented
|
LL | let x: typeof(92) = 92;
| ^^^^^^^^^^ reserved keyword
|
help: consider replacing `typeof(...)` with an actual type
|
LL | let x: i32 = 92;
| ~~~
error: aborting due to previous error

View file

@ -3,6 +3,11 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented
|
LL | let b: typeof(a) = 1i8;
| ^^^^^^^^^ reserved keyword
|
help: consider replacing `typeof(...)` with an actual type
|
LL | let b: u8 = 1i8;
| ~~
error[E0308]: mismatched types
--> $DIR/type_mismatch.rs:5:24