From 3d86b8acdab25399fc921ab6b522943a02bac410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 30 Jun 2023 03:06:15 +0000 Subject: [PATCH 1/4] Add test for #56607 --- tests/ui/sized/unsized-binding.rs | 5 ++++ tests/ui/sized/unsized-binding.stderr | 39 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/ui/sized/unsized-binding.rs create mode 100644 tests/ui/sized/unsized-binding.stderr diff --git a/tests/ui/sized/unsized-binding.rs b/tests/ui/sized/unsized-binding.rs new file mode 100644 index 0000000000000..7d41071861204 --- /dev/null +++ b/tests/ui/sized/unsized-binding.rs @@ -0,0 +1,5 @@ +fn main() { + let x = *""; //~ ERROR E0277 + println!("{}", x); //~ ERROR E0277 + println!("{}", x); //~ ERROR E0277 +} diff --git a/tests/ui/sized/unsized-binding.stderr b/tests/ui/sized/unsized-binding.stderr new file mode 100644 index 0000000000000..d508d84930aa8 --- /dev/null +++ b/tests/ui/sized/unsized-binding.stderr @@ -0,0 +1,39 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-binding.rs:2:9 + | +LL | let x = *""; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-binding.rs:3:20 + | +LL | println!("{}", x); + | -- ^ 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 `str` +note: required by a bound in `core::fmt::rt::Argument::<'a>::new_display` + --> $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[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-binding.rs:4:20 + | +LL | println!("{}", x); + | -- ^ 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 `str` +note: required by a bound in `core::fmt::rt::Argument::<'a>::new_display` + --> $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 3 previous errors + +For more information about this error, try `rustc --explain E0277`. From 2f79681fb9346ba511ad42499d12faee15e6c63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 30 Jun 2023 03:14:44 +0000 Subject: [PATCH 2/4] Only emit one error per unsized binding, instead of one per usage Fix #56607. --- .../error_reporting/type_err_ctxt_ext.rs | 19 +++++++++++++ tests/ui/sized/unsized-binding.rs | 4 +-- tests/ui/sized/unsized-binding.stderr | 28 +------------------ 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 8adfb27a3f448..18e62fd631989 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -428,6 +428,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { return; } + if let ObligationCauseCode::FunctionArgumentObligation { + arg_hir_id, + .. + } = obligation.cause.code() + && let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id) + && let arg = arg.peel_borrows() + && let hir::ExprKind::Path(hir::QPath::Resolved( + None, + hir::Path { res: hir::def::Res::Local(hir_id), .. }, + )) = arg.kind + && let Some(Node::Pat(pat)) = self.tcx.hir().find(*hir_id) + && let Some(preds) = self.reported_trait_errors.borrow().get(&pat.span) + && preds.contains(&obligation.predicate) + && self.tcx.sess.has_errors().is_some() + { + // Silence redundant errors on binding acccess that are already + // reported on the binding definition (#56607). + return; + } let trait_ref = trait_predicate.to_poly_trait_ref(); let (post_message, pre_message, type_def) = self diff --git a/tests/ui/sized/unsized-binding.rs b/tests/ui/sized/unsized-binding.rs index 7d41071861204..3b99b0f6e9654 100644 --- a/tests/ui/sized/unsized-binding.rs +++ b/tests/ui/sized/unsized-binding.rs @@ -1,5 +1,5 @@ fn main() { let x = *""; //~ ERROR E0277 - println!("{}", x); //~ ERROR E0277 - println!("{}", x); //~ ERROR E0277 + println!("{}", x); + println!("{}", x); } diff --git a/tests/ui/sized/unsized-binding.stderr b/tests/ui/sized/unsized-binding.stderr index d508d84930aa8..af306685021e0 100644 --- a/tests/ui/sized/unsized-binding.stderr +++ b/tests/ui/sized/unsized-binding.stderr @@ -8,32 +8,6 @@ LL | let x = *""; = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature -error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unsized-binding.rs:3:20 - | -LL | println!("{}", x); - | -- ^ 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 `str` -note: required by a bound in `core::fmt::rt::Argument::<'a>::new_display` - --> $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[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unsized-binding.rs:4:20 - | -LL | println!("{}", x); - | -- ^ 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 `str` -note: required by a bound in `core::fmt::rt::Argument::<'a>::new_display` - --> $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 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. From 124d6d843e1fc072ec2cd4547d60b61f99450738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 9 Oct 2023 23:14:23 +0000 Subject: [PATCH 3/4] Remove need for `has_errors()` check --- .../error_reporting/type_err_ctxt_ext.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 18e62fd631989..a3e3a964ca2d3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -163,12 +163,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { predicate: error.obligation.predicate, index: Some(index), }); - - self.reported_trait_errors - .borrow_mut() - .entry(span) - .or_default() - .push(error.obligation.predicate); } // We do this in 2 passes because we want to display errors in order, though @@ -206,6 +200,18 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { for (error, suppressed) in iter::zip(&errors, &is_suppressed) { if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { self.report_fulfillment_error(error); + // We want to ignore desugarings here: spans are equivalent even + // if one is the result of a desugaring and the other is not. + let mut span = error.obligation.cause.span; + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(_) = expn_data.kind { + span = expn_data.call_site; + } + self.reported_trait_errors + .borrow_mut() + .entry(span) + .or_default() + .push(error.obligation.predicate); } } } @@ -441,7 +447,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && let Some(Node::Pat(pat)) = self.tcx.hir().find(*hir_id) && let Some(preds) = self.reported_trait_errors.borrow().get(&pat.span) && preds.contains(&obligation.predicate) - && self.tcx.sess.has_errors().is_some() { // Silence redundant errors on binding acccess that are already // reported on the binding definition (#56607). From 568b316ce3ec25aaaecf8e63a7b3a1301f016d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 9 Oct 2023 23:18:36 +0000 Subject: [PATCH 4/4] Move predicate error early check to its own method --- .../error_reporting/type_err_ctxt_ext.rs | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index a3e3a964ca2d3..da16941b923f8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -104,6 +104,8 @@ pub trait TypeErrCtxtExt<'tcx> { error: &SelectionError<'tcx>, ); + fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool; + fn report_const_param_not_wf( &self, ty: Ty<'tcx>, @@ -434,20 +436,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { return; } - if let ObligationCauseCode::FunctionArgumentObligation { - arg_hir_id, - .. - } = obligation.cause.code() - && let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id) - && let arg = arg.peel_borrows() - && let hir::ExprKind::Path(hir::QPath::Resolved( - None, - hir::Path { res: hir::def::Res::Local(hir_id), .. }, - )) = arg.kind - && let Some(Node::Pat(pat)) = self.tcx.hir().find(*hir_id) - && let Some(preds) = self.reported_trait_errors.borrow().get(&pat.span) - && preds.contains(&obligation.predicate) - { + if self.fn_arg_obligation(&obligation) { // Silence redundant errors on binding acccess that are already // reported on the binding definition (#56607). return; @@ -948,6 +937,26 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.emit(); } + fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool { + if let ObligationCauseCode::FunctionArgumentObligation { + arg_hir_id, + .. + } = obligation.cause.code() + && let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id) + && let arg = arg.peel_borrows() + && let hir::ExprKind::Path(hir::QPath::Resolved( + None, + hir::Path { res: hir::def::Res::Local(hir_id), .. }, + )) = arg.kind + && let Some(Node::Pat(pat)) = self.tcx.hir().find(*hir_id) + && let Some(preds) = self.reported_trait_errors.borrow().get(&pat.span) + && preds.contains(&obligation.predicate) + { + return true; + } + false + } + fn report_const_param_not_wf( &self, ty: Ty<'tcx>,