Skip to content

Commit

Permalink
Rollup merge of #91981 - estebank:tweakaroo, r=lcnr
Browse files Browse the repository at this point in the history
Recover suggestions and useful information lost in previous PR

Follow up to #91898.
  • Loading branch information
Dylan-DPC authored Mar 27, 2022
2 parents 551b4fa + f479e26 commit 4435bb0
Show file tree
Hide file tree
Showing 41 changed files with 209 additions and 60 deletions.
6 changes: 5 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ pub fn same_type_modulo_infer<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
)
| (&ty::Infer(ty::InferTy::TyVar(_)), _)
| (_, &ty::Infer(ty::InferTy::TyVar(_))) => true,
(&ty::Ref(reg_a, ty_a, mut_a), &ty::Ref(reg_b, ty_b, mut_b)) => {
reg_a == reg_b && mut_a == mut_b && same_type_modulo_infer(*ty_a, *ty_b)
}
_ => a == b,
}
}
Expand Down Expand Up @@ -602,7 +605,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
match *cause.code() {
ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => {
let ty = self.resolve_vars_if_possible(root_ty);
if ty.is_suggestable() {
if !matches!(ty.kind(), ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)))
{
// don't show type `_`
err.span_label(span, format!("this expression has type `{}`", ty));
}
Expand Down
31 changes: 31 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1434,6 +1434,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
value.fold_with(&mut r)
}

pub fn resolve_numeric_literals_with_default<T>(&self, value: T) -> T
where
T: TypeFoldable<'tcx>,
{
if !value.needs_infer() {
return value; // Avoid duplicated subst-folding.
}
let mut r = InferenceLiteralEraser { tcx: self.tcx };
value.fold_with(&mut r)
}

/// Returns the first unresolved variable contained in `T`. In the
/// process of visiting `T`, this will resolve (where possible)
/// type variables in `T`, but it never constructs the final,
Expand Down Expand Up @@ -1785,6 +1796,26 @@ impl<'tcx> TyOrConstInferVar<'tcx> {
}
}

/// Replace `{integer}` with `i32` and `{float}` with `f64`.
/// Used only for diagnostics.
struct InferenceLiteralEraser<'tcx> {
tcx: TyCtxt<'tcx>,
}

impl<'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
match ty.kind() {
ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => self.tcx.types.i32,
ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => self.tcx.types.f64,
_ => ty.super_fold_with(self),
}
}
}

struct ShallowResolver<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_typeck/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::GenericArg;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::ty::{
self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, Ty, TyCtxt,
};
Expand Down Expand Up @@ -83,7 +84,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let Some(param_local_id) = param.def_id.as_local() {
let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_local_id);
let param_name = tcx.hir().ty_param_name(param_hir_id);
let param_type = tcx.type_of(param.def_id);
let param_type = tcx.infer_ctxt().enter(|infcx| {
infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id))
});
if param_type.is_suggestable() {
err.span_suggestion(
tcx.def_span(src_def_id),
Expand Down
13 changes: 11 additions & 2 deletions compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,20 +521,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
can_suggest: bool,
fn_id: hir::HirId,
) -> bool {
let found =
self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
// Only suggest changing the return type for methods that
// haven't set a return type at all (and aren't `fn main()` or an impl).
match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
(&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
err.span_suggestion(
span,
"try adding a return type",
format!("-> {} ", self.resolve_vars_with_obligations(found)),
format!("-> {} ", found),
Applicability::MachineApplicable,
);
true
}
(&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
err.span_label(span, "possibly return type missing here?");
// FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest
// that.
err.span_suggestion(
span,
"a return type might be missing here",
"-> _ ".to_string(),
Applicability::HasPlaceholders,
);
true
}
(&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/async-await/issue-61076.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ async fn baz() -> Result<(), ()> {

async fn match_() {
match tuple() { //~ HELP consider `await`ing on the `Future`
//~^ NOTE this expression has type `impl Future<Output = Tuple>`
Tuple(_) => {} //~ ERROR mismatched types
//~^ NOTE expected opaque type, found struct `Tuple`
//~| NOTE expected opaque type `impl Future<Output = Tuple>`
Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/async-await/issue-61076.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ LL | struct_().await.method();
| ++++++

error[E0308]: mismatched types
--> $DIR/issue-61076.rs:90:9
--> $DIR/issue-61076.rs:91:9
|
LL | match tuple() {
| ------- this expression has type `impl Future<Output = Tuple>`
LL |
LL | Tuple(_) => {}
| ^^^^^^^^ expected opaque type, found struct `Tuple`
|
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/async-await/suggest-missing-await.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ LL ~ 1 => dummy().await,
error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:53:9
|
LL | let _x = match dummy() {
| ------- this expression has type `impl Future<Output = ()>`
LL | () => {}
| ^^ expected opaque type, found `()`
|
Expand All @@ -109,6 +111,9 @@ LL | let _x = match dummy().await {
error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:67:9
|
LL | match dummy_result() {
| -------------- this expression has type `impl Future<Output = Result<(), ()>>`
...
LL | Ok(_) => {}
| ^^^^^ expected opaque type, found enum `Result`
|
Expand All @@ -127,6 +132,9 @@ LL | match dummy_result().await {
error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:69:9
|
LL | match dummy_result() {
| -------------- this expression has type `impl Future<Output = Result<(), ()>>`
...
LL | Err(_) => {}
| ^^^^^^ expected opaque type, found enum `Result`
|
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/blind/blind-item-block-middle.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | mod foo { pub struct bar; }
| --------------- unit struct defined here
...
LL | let bar = 5;
| ^^^
| ^^^ - this expression has type `{integer}`
| |
| expected integer, found struct `bar`
| `bar` is interpreted as a unit struct, not a new binding
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/block-result/issue-20862.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/issue-20862.rs:2:5
|
LL | fn foo(x: i32) {
| - possibly return type missing here?
| - help: a return type might be missing here: `-> _`
LL | |y| x + y
| ^^^^^^^^^ expected `()`, found closure
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ error[E0308]: mismatched types
--> $DIR/default-match-bindings-forbidden.rs:4:5
|
LL | (x, y) = &(1, 2);
| ^^^^^^ expected reference, found tuple
| ^^^^^^ ------- this expression has type `&({integer}, {integer})`
| |
| expected reference, found tuple
|
= note: expected type `&({integer}, {integer})`
found tuple `(_, _)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ error[E0308]: mismatched types
--> $DIR/tuple_destructure_fail.rs:6:5
|
LL | (a, a, b) = (1, 2);
| ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
| ^^^^^^^^^ ------ this expression has type `({integer}, {integer})`
| |
| expected a tuple with 2 elements, found one with 3 elements
|
= note: expected type `({integer}, {integer})`
found tuple `(_, _, _)`
Expand All @@ -27,7 +29,9 @@ error[E0308]: mismatched types
--> $DIR/tuple_destructure_fail.rs:8:5
|
LL | (_,) = (1, 2);
| ^^^^ expected a tuple with 2 elements, found one with 1 element
| ^^^^ ------ this expression has type `({integer}, {integer})`
| |
| expected a tuple with 2 elements, found one with 1 element
|
= note: expected type `({integer}, {integer})`
found tuple `(_,)`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision.rs:6:13
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [_, 99.., _] => {},
| ^^ expected struct `std::ops::Range`, found integer
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ LL | [_, 99..] => {},
error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:13
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [_, 99..] => {},
| ^^ expected struct `std::ops::Range`, found integer
|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:12
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [..9, 99..100, _] => {},
| ^ expected struct `std::ops::Range`, found integer
|
Expand All @@ -10,6 +12,8 @@ LL | [..9, 99..100, _] => {},
error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:15
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [..9, 99..100, _] => {},
| ^^ --- this is of type `{integer}`
| |
Expand All @@ -21,6 +25,8 @@ LL | [..9, 99..100, _] => {},
error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:6:19
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [..9, 99..100, _] => {},
| -- ^^^ expected struct `std::ops::Range`, found integer
| |
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/half-open-range-patterns/pat-tuple-5.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error[E0308]: mismatched types
--> $DIR/pat-tuple-5.rs:8:10
|
LL | match (0, 1) {
| ------ this expression has type `({integer}, {integer})`
LL | (PAT ..) => {}
| ^^^ expected tuple, found `u8`
|
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-11844.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error[E0308]: mismatched types
--> $DIR/issue-11844.rs:6:9
|
LL | match a {
| - this expression has type `Option<Box<{integer}>>`
LL | Ok(a) =>
| ^^^^^ expected enum `Option`, found enum `Result`
|
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/issues/issue-12552.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error[E0308]: mismatched types
--> $DIR/issue-12552.rs:6:5
|
LL | match t {
| - this expression has type `Result<_, {integer}>`
LL | Some(k) => match k {
| ^^^^^^^ expected enum `Result`, found enum `Option`
|
Expand All @@ -10,6 +12,9 @@ LL | Some(k) => match k {
error[E0308]: mismatched types
--> $DIR/issue-12552.rs:9:5
|
LL | match t {
| - this expression has type `Result<_, {integer}>`
...
LL | None => ()
| ^^^^ expected enum `Result`, found enum `Option`
|
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/issues/issue-13466.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error[E0308]: mismatched types
--> $DIR/issue-13466.rs:8:9
|
LL | let _x: usize = match Some(1) {
| ------- this expression has type `Option<{integer}>`
LL | Ok(u) => u,
| ^^^^^ expected enum `Option`, found enum `Result`
|
Expand All @@ -10,6 +12,9 @@ LL | Ok(u) => u,
error[E0308]: mismatched types
--> $DIR/issue-13466.rs:14:9
|
LL | let _x: usize = match Some(1) {
| ------- this expression has type `Option<{integer}>`
...
LL | Err(e) => panic!(e)
| ^^^^^^ expected enum `Option`, found enum `Result`
|
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-33504.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | struct Test;
| ------------ unit struct defined here
...
LL | let Test = 1;
| ^^^^
| ^^^^ - this expression has type `{integer}`
| |
| expected integer, found struct `Test`
| `Test` is interpreted as a unit struct, not a new binding
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-3680.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error[E0308]: mismatched types
--> $DIR/issue-3680.rs:3:9
|
LL | match None {
| ---- this expression has type `Option<_>`
LL | Err(_) => ()
| ^^^^^^ expected enum `Option`, found enum `Result`
|
Expand Down
11 changes: 6 additions & 5 deletions src/test/ui/issues/issue-4968.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ LL | const A: (isize,isize) = (4,2);
| ------------------------------- constant defined here
LL | fn main() {
LL | match 42 { A => () }
| ^
| |
| expected integer, found tuple
| `A` is interpreted as a constant, not a new binding
| help: introduce a new binding instead: `other_a`
| -- ^
| | |
| | expected integer, found tuple
| | `A` is interpreted as a constant, not a new binding
| | help: introduce a new binding instead: `other_a`
| this expression has type `{integer}`
|
= note: expected type `{integer}`
found tuple `(isize, isize)`
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-66706.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,23 @@ error[E0308]: mismatched types
--> $DIR/issue-66706.rs:2:5
|
LL | fn a() {
| - possibly return type missing here?
| - help: try adding a return type: `-> [i32; _]`
LL | [0; [|_: _ &_| ()].len()]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`

error[E0308]: mismatched types
--> $DIR/issue-66706.rs:14:5
|
LL | fn c() {
| - possibly return type missing here?
| - help: try adding a return type: `-> [i32; _]`
LL | [0; [|&_: _ &_| {}; 0 ].len()]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`

error[E0308]: mismatched types
--> $DIR/issue-66706.rs:20:5
|
LL | fn d() {
| - possibly return type missing here?
| - help: try adding a return type: `-> [i32; _]`
LL | [0; match [|f @ &ref _| () ] {} ]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-72574-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ LL | (_a, _x @ ..) => {}
error[E0308]: mismatched types
--> $DIR/issue-72574-1.rs:4:9
|
LL | match x {
| - this expression has type `({integer}, {integer}, {integer})`
LL | (_a, _x @ ..) => {}
| ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
|
Expand Down
Loading

0 comments on commit 4435bb0

Please sign in to comment.