From 467bc9ffd56dc31d6db79820bd07dbdd5f653783 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 5 Jun 2023 15:28:50 -0700 Subject: [PATCH] diagnostics: do not suggest type name tweaks on type-inferred closure args Fixes #111932 --- compiler/rustc_hir_typeck/src/check.rs | 14 +++++++++- .../rustc_hir_typeck/src/gather_locals.rs | 12 ++++++++- .../src/traits/error_reporting/suggestions.rs | 4 +-- tests/ui/closures/issue-111932.rs | 9 +++++++ tests/ui/closures/issue-111932.stderr | 26 +++++++++++++++++++ tests/ui/unsized-locals/issue-67981.stderr | 5 +--- 6 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 tests/ui/closures/issue-111932.rs create mode 100644 tests/ui/closures/issue-111932.stderr diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index bfabd44bb5792..69ccbf0b58ff3 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -96,7 +96,19 @@ pub(super) fn check_fn<'a, 'tcx>( // for simple cases like `fn foo(x: Trait)`, // where we would error once on the parameter as a whole, and once on the binding `x`. if param.pat.simple_ident().is_none() && !params_can_be_unsized { - fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span)); + fcx.require_type_is_sized( + param_ty, + param.pat.span, + // ty_span == binding_span iff this is a closure parameter with no type ascription, + // or if it's an implicit `self` parameter + traits::SizedArgumentType( + if ty_span == Some(param.span) && tcx.is_closure(fn_def_id.into()) { + None + } else { + ty_span + }, + ), + ); } fcx.write_ty(param.hir_id, param_ty); diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index 38445f2844052..d9b9b34ba583b 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -129,7 +129,17 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { self.fcx.require_type_is_sized( var_ty, p.span, - traits::SizedArgumentType(Some(ty_span)), + // ty_span == ident.span iff this is a closure parameter with no type + // ascription, or if it's an implicit `self` parameter + traits::SizedArgumentType( + if ty_span == ident.span + && self.fcx.tcx.is_closure(self.fcx.body_id.into()) + { + None + } else { + Some(ty_span) + }, + ), ); } } else { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 42038dbc3d82e..01f2782fd284e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2807,8 +2807,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.help("unsized locals are gated as an unstable feature"); } } - ObligationCauseCode::SizedArgumentType(sp) => { - if let Some(span) = sp { + ObligationCauseCode::SizedArgumentType(ty_span) => { + if let Some(span) = ty_span { if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() && let ty::Clause::Trait(trait_pred) = clause && let ty::Dynamic(..) = trait_pred.self_ty().kind() diff --git a/tests/ui/closures/issue-111932.rs b/tests/ui/closures/issue-111932.rs new file mode 100644 index 0000000000000..eb3fe08cbc409 --- /dev/null +++ b/tests/ui/closures/issue-111932.rs @@ -0,0 +1,9 @@ +trait Foo: std::fmt::Debug {} + +fn print_foos(foos: impl Iterator) { + foos.for_each(|foo| { //~ ERROR [E0277] + println!("{:?}", foo); //~ ERROR [E0277] + }); +} + +fn main() {} diff --git a/tests/ui/closures/issue-111932.stderr b/tests/ui/closures/issue-111932.stderr new file mode 100644 index 0000000000000..937bdf3bea255 --- /dev/null +++ b/tests/ui/closures/issue-111932.stderr @@ -0,0 +1,26 @@ +error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time + --> $DIR/issue-111932.rs:4:20 + | +LL | foos.for_each(|foo| { + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` + = note: all function arguments must have a statically known size + = help: unsized fn params are gated as an unstable feature + +error[E0277]: the size for values of type `dyn Foo` cannot be known at compilation time + --> $DIR/issue-111932.rs:5:26 + | +LL | println!("{:?}", foo); + | ---- ^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `dyn Foo` +note: required by a bound in `core::fmt::rt::Argument::<'a>::new_debug` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unsized-locals/issue-67981.stderr b/tests/ui/unsized-locals/issue-67981.stderr index a4b179ae2fd12..13fdc037ac569 100644 --- a/tests/ui/unsized-locals/issue-67981.stderr +++ b/tests/ui/unsized-locals/issue-67981.stderr @@ -5,10 +5,7 @@ LL | let f: fn([u8]) = |_| {}; | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -help: function arguments must have a statically known size, borrowed types always have a known size - | -LL | let f: fn([u8]) = |&_| {}; - | + + = note: all function arguments must have a statically known size error: aborting due to previous error