Skip to content

Commit fde1f15

Browse files
committed
Account for -> ?Sized fn calls when deduplicating unsized local errors
1 parent 43a6684 commit fde1f15

File tree

6 files changed

+13
-15
lines changed

6 files changed

+13
-15
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
596596
self.require_type_is_sized_deferred(
597597
output,
598598
call.map_or(expr.span, |e| e.span),
599-
traits::SizedCallReturnType,
599+
traits::SizedCallReturnType(call.map(|e| e.hir_id)),
600600
);
601601
}
602602

compiler/rustc_middle/src/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ pub enum ObligationCauseCode<'tcx> {
293293
/// Return type must be `Sized`.
294294
SizedReturnType,
295295
/// Return type of a call expression must be `Sized`.
296-
SizedCallReturnType,
296+
SizedCallReturnType(Option<hir::HirId>),
297297
/// Yield type must be `Sized`.
298298
SizedYieldType,
299299
/// Inline asm operand type must be `Sized`.

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -3257,7 +3257,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
32573257
err.help("unsized fn params are gated as an unstable feature");
32583258
}
32593259
}
3260-
ObligationCauseCode::SizedReturnType | ObligationCauseCode::SizedCallReturnType => {
3260+
ObligationCauseCode::SizedReturnType | ObligationCauseCode::SizedCallReturnType(_) => {
32613261
err.note("the return type of a function must have a statically known size");
32623262
}
32633263
ObligationCauseCode::SizedYieldType => {

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

+8
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
131131
span = pat.span;
132132
}
133133
}
134+
ObligationCauseCode::SizedCallReturnType(Some(hir_id)) => {
135+
// This is a special case: when `fn foo() -> dyn Trait` and we call `foo()`
136+
// in the init of a `let` binding, we will already emit an unsized local
137+
// error, so we check for this case and unify the errors.
138+
if let hir::Node::Local(local) = self.tcx.parent_hir_node(*hir_id) {
139+
span = local.pat.span;
140+
}
141+
}
134142
_ => {}
135143
}
136144
}

tests/ui/sized/unsized-return.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ fn foo() -> dyn T { //~ E0746
66

77
fn main() {
88
let x = foo(); //~ ERROR E0277
9-
//~^ ERROR E0277
109
let x: dyn T = foo(); //~ ERROR E0277
1110
}

tests/ui/sized/unsized-return.stderr

+2-11
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ LL ~ Box::new(todo!())
1616
|
1717

1818
error[E0277]: the size for values of type `dyn T` cannot be known at compilation time
19-
--> $DIR/unsized-return.rs:10:12
19+
--> $DIR/unsized-return.rs:9:12
2020
|
2121
LL | let x: dyn T = foo();
2222
| ^^^^^ doesn't have a size known at compile-time
@@ -39,16 +39,7 @@ LL | let x = foo();
3939
= note: all local variables must have a statically known size
4040
= help: unsized locals are gated as an unstable feature
4141

42-
error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time
43-
--> $DIR/unsized-return.rs:8:13
44-
|
45-
LL | let x = foo();
46-
| ^^^^^ doesn't have a size known at compile-time
47-
|
48-
= help: the trait `Sized` is not implemented for `(dyn T + 'static)`
49-
= note: the return type of a function must have a statically known size
50-
51-
error: aborting due to 4 previous errors
42+
error: aborting due to 3 previous errors
5243

5344
Some errors have detailed explanations: E0277, E0746.
5445
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)