Skip to content

Commit aa91057

Browse files
committed
Auto merge of #113183 - estebank:redundant-sized-errors, r=davidtwco
Only emit one error per unsized binding, instead of one per usage Fix #56607.
2 parents dab7156 + 568b316 commit aa91057

File tree

3 files changed

+57
-6
lines changed

3 files changed

+57
-6
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+39-6
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ pub trait TypeErrCtxtExt<'tcx> {
9898
error: &SelectionError<'tcx>,
9999
);
100100

101+
fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool;
102+
101103
fn report_const_param_not_wf(
102104
&self,
103105
ty: Ty<'tcx>,
@@ -157,12 +159,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
157159
predicate: error.obligation.predicate,
158160
index: Some(index),
159161
});
160-
161-
self.reported_trait_errors
162-
.borrow_mut()
163-
.entry(span)
164-
.or_default()
165-
.push(error.obligation.predicate);
166162
}
167163

168164
// 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> {
200196
for (error, suppressed) in iter::zip(&errors, &is_suppressed) {
201197
if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
202198
self.report_fulfillment_error(error);
199+
// We want to ignore desugarings here: spans are equivalent even
200+
// if one is the result of a desugaring and the other is not.
201+
let mut span = error.obligation.cause.span;
202+
let expn_data = span.ctxt().outer_expn_data();
203+
if let ExpnKind::Desugaring(_) = expn_data.kind {
204+
span = expn_data.call_site;
205+
}
206+
self.reported_trait_errors
207+
.borrow_mut()
208+
.entry(span)
209+
.or_default()
210+
.push(error.obligation.predicate);
203211
}
204212
}
205213
}
@@ -412,6 +420,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
412420
{
413421
return;
414422
}
423+
if self.fn_arg_obligation(&obligation) {
424+
// Silence redundant errors on binding acccess that are already
425+
// reported on the binding definition (#56607).
426+
return;
427+
}
415428
let trait_ref = trait_predicate.to_poly_trait_ref();
416429

417430
let (post_message, pre_message, type_def) = self
@@ -908,6 +921,26 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
908921
err.emit();
909922
}
910923

924+
fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool {
925+
if let ObligationCauseCode::FunctionArgumentObligation {
926+
arg_hir_id,
927+
..
928+
} = obligation.cause.code()
929+
&& let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id)
930+
&& let arg = arg.peel_borrows()
931+
&& let hir::ExprKind::Path(hir::QPath::Resolved(
932+
None,
933+
hir::Path { res: hir::def::Res::Local(hir_id), .. },
934+
)) = arg.kind
935+
&& let Some(Node::Pat(pat)) = self.tcx.hir().find(*hir_id)
936+
&& let Some(preds) = self.reported_trait_errors.borrow().get(&pat.span)
937+
&& preds.contains(&obligation.predicate)
938+
{
939+
return true;
940+
}
941+
false
942+
}
943+
911944
fn report_const_param_not_wf(
912945
&self,
913946
ty: Ty<'tcx>,

tests/ui/sized/unsized-binding.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
let x = *""; //~ ERROR E0277
3+
println!("{}", x);
4+
println!("{}", x);
5+
}

tests/ui/sized/unsized-binding.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0277]: the size for values of type `str` cannot be known at compilation time
2+
--> $DIR/unsized-binding.rs:2:9
3+
|
4+
LL | let x = *"";
5+
| ^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `str`
8+
= note: all local variables must have a statically known size
9+
= help: unsized locals are gated as an unstable feature
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)