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:
commit
aa91057796
3 changed files with 57 additions and 6 deletions
|
@ -98,6 +98,8 @@ pub trait TypeErrCtxtExt<'tcx> {
|
||||||
error: &SelectionError<'tcx>,
|
error: &SelectionError<'tcx>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool;
|
||||||
|
|
||||||
fn report_const_param_not_wf(
|
fn report_const_param_not_wf(
|
||||||
&self,
|
&self,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
|
@ -157,12 +159,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
predicate: error.obligation.predicate,
|
predicate: error.obligation.predicate,
|
||||||
index: Some(index),
|
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
|
// 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) {
|
for (error, suppressed) in iter::zip(&errors, &is_suppressed) {
|
||||||
if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
|
if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
|
||||||
self.report_fulfillment_error(error);
|
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;
|
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 trait_ref = trait_predicate.to_poly_trait_ref();
|
||||||
|
|
||||||
let (post_message, pre_message, type_def) = self
|
let (post_message, pre_message, type_def) = self
|
||||||
|
@ -908,6 +921,26 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
err.emit();
|
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(
|
fn report_const_param_not_wf(
|
||||||
&self,
|
&self,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
|
|
5
tests/ui/sized/unsized-binding.rs
Normal file
5
tests/ui/sized/unsized-binding.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fn main() {
|
||||||
|
let x = *""; //~ ERROR E0277
|
||||||
|
println!("{}", x);
|
||||||
|
println!("{}", x);
|
||||||
|
}
|
13
tests/ui/sized/unsized-binding.stderr
Normal file
13
tests/ui/sized/unsized-binding.stderr
Normal 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`.
|
Loading…
Add table
Add a link
Reference in a new issue