Auto merge of #113183 - estebank:redundant-sized-errors, r=davidtwco

Only emit one error per unsized binding, instead of one per usage

Fix #56607.
This commit is contained in:
bors 2023-10-27 00:06:12 +00:00
commit aa91057796
3 changed files with 57 additions and 6 deletions

View File

@ -98,6 +98,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>,
@ -157,12 +159,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
@ -200,6 +196,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);
}
}
}
@ -412,6 +420,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{
return;
}
if self.fn_arg_obligation(&obligation) {
// 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
@ -908,6 +921,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>,

View File

@ -0,0 +1,5 @@
fn main() {
let x = *""; //~ ERROR E0277
println!("{}", x);
println!("{}", x);
}

View File

@ -0,0 +1,13 @@
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: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.