-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide structured suggestion to use trait objects in some cases of if
arm type divergence
#120261
Merged
Conversation
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
When encountering ```rust let _ = if true { Struct } else { foo() // -> Box<dyn Trait> }; ``` if `Struct` implements `Trait`, suggest boxing the then arm tail expression. Part of rust-lang#102629.
…olving `impl Trait` When encountering the following ```rust // run-rustfix trait Trait {} struct Struct; impl Trait for Struct {} fn foo() -> Box<dyn Trait> { Box::new(Struct) } fn bar() -> impl Trait { Struct } fn main() { let _ = if true { Struct } else { foo() //~ ERROR E0308 }; let _ = if true { foo() } else { Struct //~ ERROR E0308 }; let _ = if true { Struct } else { bar() // impl Trait }; let _ = if true { bar() // impl Trait } else { Struct }; } ``` suggest boxing both arms ```rust let _ = if true { Box::new(Struct) as Box<dyn Trait> } else { Box::new(bar()) }; let _ = if true { Box::new(bar()) as Box<dyn Trait> } else { Box::new(Struct) }; ```
r? @wesleywiser (rustbot has picked a reviewer for you, use r? to override) |
rustbot
added
S-waiting-on-review
Status: Awaiting review from the assignee but also interested parties.
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
labels
Jan 23, 2024
wesleywiser
approved these changes
Jan 23, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! 🏅
@bors r+ rollup |
bors
added
S-waiting-on-bors
Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
and removed
S-waiting-on-review
Status: Awaiting review from the assignee but also interested parties.
labels
Jan 23, 2024
fmease
added a commit
to fmease/rust
that referenced
this pull request
Jan 23, 2024
Provide structured suggestion to use trait objects in some cases of `if` arm type divergence ``` error[E0308]: `if` and `else` have incompatible types --> $DIR/suggest-box-on-divergent-if-else-arms.rs:15:9 | LL | let _ = if true { | _____________- LL | | Struct | | ------ expected because of this LL | | } else { LL | | foo() | | ^^^^^ expected `Struct`, found `Box<dyn Trait>` LL | | }; | |_____- `if` and `else` have incompatible types | = note: expected struct `Struct` found struct `Box<dyn Trait>` help: `Struct` implements `Trait` so you can box it to coerce to the trait object `Box<dyn Trait>` | LL | Box::new(Struct) | +++++++++ + error[E0308]: `if` and `else` have incompatible types --> $DIR/suggest-box-on-divergent-if-else-arms.rs:20:9 | LL | let _ = if true { | _____________- LL | | foo() | | ----- expected because of this LL | | } else { LL | | Struct | | ^^^^^^ expected `Box<dyn Trait>`, found `Struct` LL | | }; | |_____- `if` and `else` have incompatible types | = note: expected struct `Box<dyn Trait>` found struct `Struct` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html help: store this in the heap by calling `Box::new` | LL | Box::new(Struct) | +++++++++ + error[E0308]: `if` and `else` have incompatible types --> $DIR/suggest-box-on-divergent-if-else-arms.rs:25:9 | LL | fn bar() -> impl Trait { | ---------- the found opaque type ... LL | let _ = if true { | _____________- LL | | Struct | | ------ expected because of this LL | | } else { LL | | bar() | | ^^^^^ expected `Struct`, found opaque type LL | | }; | |_____- `if` and `else` have incompatible types | = note: expected struct `Struct` found opaque type `impl Trait` help: `Struct` implements `Trait` so you can box both arms and coerce to the trait object `Box<dyn Trait>` | LL ~ Box::new(Struct) as Box<dyn Trait> LL | } else { LL ~ Box::new(bar()) | error[E0308]: `if` and `else` have incompatible types --> $DIR/suggest-box-on-divergent-if-else-arms.rs:30:9 | LL | fn bar() -> impl Trait { | ---------- the expected opaque type ... LL | let _ = if true { | _____________- LL | | bar() | | ----- expected because of this LL | | } else { LL | | Struct | | ^^^^^^ expected opaque type, found `Struct` LL | | }; | |_____- `if` and `else` have incompatible types | = note: expected opaque type `impl Trait` found struct `Struct` help: `Struct` implements `Trait` so you can box both arms and coerce to the trait object `Box<dyn Trait>` | LL ~ Box::new(bar()) as Box<dyn Trait> LL | } else { LL ~ Box::new(Struct) | ``` Partially address rust-lang#102629.
bors
added a commit
to rust-lang-ci/rust
that referenced
this pull request
Jan 23, 2024
Rollup of 12 pull requests Successful merges: - rust-lang#112806 (Small code improvements in `collect_intra_doc_links.rs`) - rust-lang#119460 (coverage: Never emit improperly-ordered coverage regions) - rust-lang#119766 (Split tait and impl trait in assoc items logic) - rust-lang#120062 (llvm: change data layout bug to an error and make it trigger more) - rust-lang#120099 (linker: Refactor library linking methods in `trait Linker`) - rust-lang#120139 (Do not normalize closure signature when building `FnOnce` shim) - rust-lang#120160 (Manually implement derived `NonZero` traits.) - rust-lang#120171 (Fix assume and assert in jump threading) - rust-lang#120183 (Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`) - rust-lang#120195 (add several resolution test cases) - rust-lang#120259 (Split Diagnostics for Uncommon Codepoints: Add List to Display Characters Involved) - rust-lang#120261 (Provide structured suggestion to use trait objects in some cases of `if` arm type divergence) r? `@ghost` `@rustbot` modify labels: rollup
bors
added a commit
to rust-lang-ci/rust
that referenced
this pull request
Jan 23, 2024
Rollup of 9 pull requests Successful merges: - rust-lang#112806 (Small code improvements in `collect_intra_doc_links.rs`) - rust-lang#119766 (Split tait and impl trait in assoc items logic) - rust-lang#120139 (Do not normalize closure signature when building `FnOnce` shim) - rust-lang#120160 (Manually implement derived `NonZero` traits.) - rust-lang#120171 (Fix assume and assert in jump threading) - rust-lang#120183 (Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`) - rust-lang#120195 (add several resolution test cases) - rust-lang#120259 (Split Diagnostics for Uncommon Codepoints: Add List to Display Characters Involved) - rust-lang#120261 (Provide structured suggestion to use trait objects in some cases of `if` arm type divergence) r? `@ghost` `@rustbot` modify labels: rollup
rust-timer
added a commit
to rust-lang-ci/rust
that referenced
this pull request
Jan 24, 2024
Rollup merge of rust-lang#120261 - estebank:issue-102629, r=wesleywiser Provide structured suggestion to use trait objects in some cases of `if` arm type divergence ``` error[E0308]: `if` and `else` have incompatible types --> $DIR/suggest-box-on-divergent-if-else-arms.rs:15:9 | LL | let _ = if true { | _____________- LL | | Struct | | ------ expected because of this LL | | } else { LL | | foo() | | ^^^^^ expected `Struct`, found `Box<dyn Trait>` LL | | }; | |_____- `if` and `else` have incompatible types | = note: expected struct `Struct` found struct `Box<dyn Trait>` help: `Struct` implements `Trait` so you can box it to coerce to the trait object `Box<dyn Trait>` | LL | Box::new(Struct) | +++++++++ + error[E0308]: `if` and `else` have incompatible types --> $DIR/suggest-box-on-divergent-if-else-arms.rs:20:9 | LL | let _ = if true { | _____________- LL | | foo() | | ----- expected because of this LL | | } else { LL | | Struct | | ^^^^^^ expected `Box<dyn Trait>`, found `Struct` LL | | }; | |_____- `if` and `else` have incompatible types | = note: expected struct `Box<dyn Trait>` found struct `Struct` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html help: store this in the heap by calling `Box::new` | LL | Box::new(Struct) | +++++++++ + error[E0308]: `if` and `else` have incompatible types --> $DIR/suggest-box-on-divergent-if-else-arms.rs:25:9 | LL | fn bar() -> impl Trait { | ---------- the found opaque type ... LL | let _ = if true { | _____________- LL | | Struct | | ------ expected because of this LL | | } else { LL | | bar() | | ^^^^^ expected `Struct`, found opaque type LL | | }; | |_____- `if` and `else` have incompatible types | = note: expected struct `Struct` found opaque type `impl Trait` help: `Struct` implements `Trait` so you can box both arms and coerce to the trait object `Box<dyn Trait>` | LL ~ Box::new(Struct) as Box<dyn Trait> LL | } else { LL ~ Box::new(bar()) | error[E0308]: `if` and `else` have incompatible types --> $DIR/suggest-box-on-divergent-if-else-arms.rs:30:9 | LL | fn bar() -> impl Trait { | ---------- the expected opaque type ... LL | let _ = if true { | _____________- LL | | bar() | | ----- expected because of this LL | | } else { LL | | Struct | | ^^^^^^ expected opaque type, found `Struct` LL | | }; | |_____- `if` and `else` have incompatible types | = note: expected opaque type `impl Trait` found struct `Struct` help: `Struct` implements `Trait` so you can box both arms and coerce to the trait object `Box<dyn Trait>` | LL ~ Box::new(bar()) as Box<dyn Trait> LL | } else { LL ~ Box::new(Struct) | ``` Partially address rust-lang#102629.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
S-waiting-on-bors
Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Partially address #102629.