Skip to content

Commit db7f308

Browse files
committed
Further dedup unsized locals errors involving method calls
1 parent b9dc405 commit db7f308

File tree

6 files changed

+26
-23
lines changed

6 files changed

+26
-23
lines changed

compiler/rustc_hir_typeck/src/gather_locals.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -138,22 +138,32 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
138138
self.fcx.ty_to_string(*self.fcx.locals.borrow().get(&decl.hir_id).unwrap())
139139
);
140140
}
141+
142+
fn span_for_init_expr(&self, expr: &'tcx hir::Expr<'tcx>) -> Span {
143+
// In other parts of the compiler, when emitting a bound error on a method call we point at
144+
// the method call path. We mimic that here so that error deduplication will work as
145+
// expected.
146+
match expr.kind {
147+
hir::ExprKind::MethodCall(path, ..) => path.ident.span,
148+
_ => expr.span,
149+
}
150+
}
141151
}
142152

143153
impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
144154
// Add explicitly-declared locals.
145155
fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) {
146156
self.declare(local.into());
147157
let sp = self.let_binding_init.take();
148-
self.let_binding_init = local.init.map(|e| e.span);
158+
self.let_binding_init = local.init.map(|e| self.span_for_init_expr(e));
149159
intravisit::walk_local(self, local);
150160
self.let_binding_init = sp;
151161
}
152162

153163
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
154164
let sp = self.let_binding_init.take();
155165
if let hir::ExprKind::Let(let_expr) = expr.kind {
156-
self.let_binding_init = Some(let_expr.init.span);
166+
self.let_binding_init = Some(self.span_for_init_expr(&let_expr.init));
157167
self.declare((let_expr, expr.hir_id).into());
158168
}
159169
intravisit::walk_expr(self, expr);

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

+6
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
139139
span = local.pat.span;
140140
}
141141
}
142+
ObligationCauseCode::ExprBindingObligation(_, _, hir_id, _) => {
143+
// For method calls like `let x = y.foo();` that are `?Sized`, we also dedup
144+
if let hir::Node::Local(local) = self.tcx.parent_hir_node(*hir_id) {
145+
span = local.pat.span;
146+
}
147+
}
142148
_ => {}
143149
}
144150
}

tests/ui/associated-types/associated-types-unsized.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the size for values of type `<T as Get>::Value` cannot be known at compilation time
2-
--> $DIR/associated-types-unsized.rs:10:13
2+
--> $DIR/associated-types-unsized.rs:10:15
33
|
44
LL | let x = t.get();
5-
| ^^^^^^^ doesn't have a size known at compile-time
5+
| ^^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `Sized` is not implemented for `<T as Get>::Value`
88
= note: all local variables must have a statically known size

tests/ui/error-codes/E0038.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ LL | fn foo(&self) -> Self;
2929
= help: consider moving `foo` to another trait
3030

3131
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
32-
--> $DIR/E0038.rs:7:13
32+
--> $DIR/E0038.rs:7:15
3333
|
3434
LL | let y = x.foo();
35-
| ^^^^^^^ doesn't have a size known at compile-time
35+
| ^^^ doesn't have a size known at compile-time
3636
|
3737
= help: the trait `Sized` is not implemented for `dyn Trait`
3838
= note: all local variables must have a statically known size

tests/ui/iterators/collect-into-slice.rs

-3
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,11 @@ fn process_slice(data: &[i32]) {
55
fn main() {
66
let some_generated_vec = (0..10).collect();
77
//~^ ERROR the size for values of type `[i32]` cannot be known at compilation time
8-
//~| ERROR the size for values of type `[i32]` cannot be known at compilation time
98
//~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size
109
//~| NOTE try explicitly collecting into a `Vec<{integer}>`
11-
//~| NOTE required by an implicit `Sized` bound in `collect`
1210
//~| NOTE required by a bound in `collect`
1311
//~| NOTE all local variables must have a statically known size
1412
//~| NOTE doesn't have a size known at compile-time
15-
//~| NOTE doesn't have a size known at compile-time
1613
process_slice(&some_generated_vec);
1714

1815
let some_generated_vec = (0..10).collect();

tests/ui/iterators/collect-into-slice.stderr

+4-14
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,18 @@ LL | let some_generated_vec = (0..10).collect();
88
note: required by a bound in `collect`
99
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
1010

11-
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
12-
--> $DIR/collect-into-slice.rs:6:30
13-
|
14-
LL | let some_generated_vec = (0..10).collect();
15-
| ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
16-
|
17-
= help: the trait `Sized` is not implemented for `[i32]`
18-
= note: all local variables must have a statically known size
19-
= help: unsized locals are gated as an unstable feature
20-
2111
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
2212
--> $DIR/collect-into-slice.rs:6:38
2313
|
2414
LL | let some_generated_vec = (0..10).collect();
2515
| ^^^^^^^ doesn't have a size known at compile-time
2616
|
2717
= help: the trait `Sized` is not implemented for `[i32]`
28-
note: required by an implicit `Sized` bound in `collect`
29-
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
18+
= note: all local variables must have a statically known size
19+
= help: unsized locals are gated as an unstable feature
3020

3121
error[E0277]: a slice of type `&[i32]` cannot be built since we need to store the elements somewhere
32-
--> $DIR/collect-into-slice.rs:18:38
22+
--> $DIR/collect-into-slice.rs:15:38
3323
|
3424
LL | let some_generated_vec = (0..10).collect();
3525
| ^^^^^^^ try explicitly collecting into a `Vec<{integer}>`
@@ -38,6 +28,6 @@ LL | let some_generated_vec = (0..10).collect();
3828
note: required by a bound in `collect`
3929
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
4030

41-
error: aborting due to 4 previous errors
31+
error: aborting due to 3 previous errors
4232

4333
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)