-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of #95603 - compiler-errors:dyn-return, r=oli-obk
Fix late-bound ICE in `dyn` return type suggestion This fixes the root-cause of the attached issues -- the root problem is that we're using the return type from a signature with late-bound instead of early-bound regions. The change on line 1087 (`let Some(liberated_sig) = typeck_results.liberated_fn_sigs().get(fn_hir_id) else { return false; };`) makes sure we're grabbing the _right_ return type for this suggestion to check the `dyn` predicates with. Fixes #91801 Fixes #91803 This fix also includes some drive-by changes, specifically: 1. Don't suggest boxing when we have `-> dyn Trait` and are already returning `Box<T>` where `T: Trait` (before we always boxed the value). 2. Suggestion applies even when the return type is a type alias (e.g. `type Foo = dyn Trait`). This does cause the suggestion to expand to the aliased type, but I think it's still beneficial. 3. Split up the multipart suggestion because there's a 6-line max in the printed output... I am open to splitting out the above changes, if we just want to fix the ICE first. cc: ```@terrarier2111``` and #92289
- Loading branch information
Showing
10 changed files
with
242 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
use std::fmt::Debug; | ||
|
||
// Test to suggest boxing the return type, and the closure branch of the `if` | ||
|
||
fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a { | ||
//~^ ERROR return type cannot have an unboxed trait object | ||
if a % 2 == 0 { | ||
move || println!("{a}") | ||
} else { | ||
Box::new(move || println!("{}", b)) | ||
//~^ ERROR `if` and `else` have incompatible types | ||
} | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
error[E0308]: `if` and `else` have incompatible types | ||
--> $DIR/box-instead-of-dyn-fn.rs:10:9 | ||
| | ||
LL | / if a % 2 == 0 { | ||
LL | | move || println!("{a}") | ||
| | ----------------------- expected because of this | ||
LL | | } else { | ||
LL | | Box::new(move || println!("{}", b)) | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found struct `Box` | ||
LL | | | ||
LL | | } | ||
| |_____- `if` and `else` have incompatible types | ||
| | ||
= note: expected type `[closure@$DIR/box-instead-of-dyn-fn.rs:8:9: 8:32]` | ||
found struct `Box<[closure@$DIR/box-instead-of-dyn-fn.rs:10:18: 10:43]>` | ||
|
||
error[E0746]: return type cannot have an unboxed trait object | ||
--> $DIR/box-instead-of-dyn-fn.rs:5:56 | ||
| | ||
LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a { | ||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time | ||
| | ||
= note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> | ||
= note: if all the returned values were of the same type you could use `impl Fn() + 'a` as the return type | ||
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> | ||
= note: you can create a new `enum` with a variant for each returned type | ||
help: return a boxed trait object instead | ||
| | ||
LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> Box<dyn Fn() + 'a> { | ||
| ++++ + | ||
help: ... and box this value | ||
| | ||
LL | Box::new(move || println!("{a}")) | ||
| +++++++++ + | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
Some errors have detailed explanations: E0308, E0746. | ||
For more information about an error, try `rustc --explain E0308`. |
Oops, something went wrong.