From 9b77a1e571041716ad0c446afd87949d40ed4de6 Mon Sep 17 00:00:00 2001 From: Hirochika Matsumoto Date: Thu, 2 Dec 2021 19:22:46 +0900 Subject: [PATCH] Don't suggest types whose inner type is erroneous Currently, we check if the returned type equals to `tcx.ty_error()` not to emit erroneous types, but this has a pitfall; for example, `Option<[type error]> != tcx.ty_error()` holds. --- compiler/rustc_typeck/src/collect.rs | 4 ++-- .../ui/typeck/issue-91450-inner-ty-error.rs | 7 +++++++ .../typeck/issue-91450-inner-ty-error.stderr | 21 +++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/typeck/issue-91450-inner-ty-error.rs create mode 100644 src/test/ui/typeck/issue-91450-inner-ty-error.stderr diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 4b41730ffd50b..f88260c0a8bf5 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -41,7 +41,7 @@ use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::Discr; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, Ty, TyCtxt}; -use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness}; +use rustc_middle::ty::{ReprOptions, ToPredicate, TypeFoldable, WithConstness}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1779,7 +1779,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { visitor.visit_ty(ty); let mut diag = bad_placeholder_type(tcx, visitor.0, "return type"); let ret_ty = fn_sig.skip_binder().output(); - if ret_ty != tcx.ty_error() { + if !ret_ty.references_error() { if !ret_ty.is_closure() { let ret_ty_str = match ret_ty.kind() { // Suggest a function pointer return type instead of a unique function definition diff --git a/src/test/ui/typeck/issue-91450-inner-ty-error.rs b/src/test/ui/typeck/issue-91450-inner-ty-error.rs new file mode 100644 index 0000000000000..0b942d6d94f84 --- /dev/null +++ b/src/test/ui/typeck/issue-91450-inner-ty-error.rs @@ -0,0 +1,7 @@ +// Regression test for #91450. +// This test ensures that the compiler does not suggest `Foo<[type error]>` in diagnostic messages. + +fn foo() -> Option<_> {} //~ ERROR: [E0308] +//~^ ERROR: the type placeholder `_` is not allowed + +fn main() {} diff --git a/src/test/ui/typeck/issue-91450-inner-ty-error.stderr b/src/test/ui/typeck/issue-91450-inner-ty-error.stderr new file mode 100644 index 0000000000000..314fe56180368 --- /dev/null +++ b/src/test/ui/typeck/issue-91450-inner-ty-error.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/issue-91450-inner-ty-error.rs:4:13 + | +LL | fn foo() -> Option<_> {} + | --- ^^^^^^^^^ expected enum `Option`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected enum `Option<_>` + found unit type `()` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-91450-inner-ty-error.rs:4:20 + | +LL | fn foo() -> Option<_> {} + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0121, E0308. +For more information about an error, try `rustc --explain E0121`.