Skip to content

Commit

Permalink
Rollup merge of rust-lang#81991 - osa1:issue81839, r=estebank
Browse files Browse the repository at this point in the history
Fix panic in 'remove semicolon' when types are not local

It's not possible to check if removing a semicolon fixes the type error
when checking match arms and one or both of the last arm's and the
current arm's return types are imported "opaque" types. In these cases
we don't generate a "consider removing semicolon" suggestions.

Fixes rust-lang#81839

---

I'm not sure how to add a test for this. I think the test would need at least two crates. Do we have any existing tests that do this so that I can take a look?
  • Loading branch information
Dylan-DPC authored Feb 20, 2021
2 parents b7b2d58 + 9ef67e0 commit 71ee3c8
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 8 deletions.
17 changes: 15 additions & 2 deletions compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1074,13 +1074,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let last_expr_ty = self.node_ty(last_expr.hir_id);
let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) {
(ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _))
if last_def_id == exp_def_id =>
{
StatementAsExpression::CorrectType
}
(ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => {
debug!(
"both opaque, likely future {:?} {:?} {:?} {:?}",
last_def_id, last_bounds, exp_def_id, exp_bounds
);
let last_hir_id = self.tcx.hir().local_def_id_to_hir_id(last_def_id.expect_local());
let exp_hir_id = self.tcx.hir().local_def_id_to_hir_id(exp_def_id.expect_local());

let (last_local_id, exp_local_id) =
match (last_def_id.as_local(), exp_def_id.as_local()) {
(Some(last_hir_id), Some(exp_hir_id)) => (last_hir_id, exp_hir_id),
(_, _) => return None,
};

let last_hir_id = self.tcx.hir().local_def_id_to_hir_id(last_local_id);
let exp_hir_id = self.tcx.hir().local_def_id_to_hir_id(exp_local_id);

match (
&self.tcx.hir().expect_item(last_hir_id).kind,
&self.tcx.hir().expect_item(exp_hir_id).kind,
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/suggestions/auxiliary/issue-81839.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// edition:2018

pub struct Test {}

impl Test {
pub async fn answer_str(&self, _s: &str) -> Test {
Test {}
}
}
17 changes: 17 additions & 0 deletions src/test/ui/suggestions/issue-81839.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// aux-build:issue-81839.rs
// edition:2018

extern crate issue_81839;

async fn test(ans: &str, num: i32, cx: &issue_81839::Test) -> u32 {
match num {
1 => {
cx.answer_str("hi");
}
_ => cx.answer_str("hi"), //~ `match` arms have incompatible types
}

1
}

fn main() {}
27 changes: 27 additions & 0 deletions src/test/ui/suggestions/issue-81839.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0308]: `match` arms have incompatible types
--> $DIR/issue-81839.rs:11:14
|
LL | / match num {
LL | | 1 => {
LL | | cx.answer_str("hi");
| | --------------------
| | | |
| | | help: consider removing this semicolon
| | this is found to be of type `()`
LL | | }
LL | | _ => cx.answer_str("hi"),
| | ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type
LL | | }
| |_____- `match` arms have incompatible types
|
::: $DIR/auxiliary/issue-81839.rs:6:49
|
LL | pub async fn answer_str(&self, _s: &str) -> Test {
| ---- the `Output` of this `async fn`'s found opaque type
|
= note: expected type `()`
found opaque type `impl Future`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
9 changes: 3 additions & 6 deletions src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,10 @@ help: consider `await`ing on the `Future`
|
LL | false => async_dummy().await,
| ^^^^^^
help: consider removing this semicolon and boxing the expressions
|
LL | Box::new(async_dummy())
LL |
LL | }
LL | false => Box::new(async_dummy()),
help: consider removing this semicolon
|
LL | async_dummy()
| --

error[E0308]: `match` arms have incompatible types
--> $DIR/match-prev-arm-needing-semi.rs:39:18
Expand Down

0 comments on commit 71ee3c8

Please sign in to comment.