diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 234a573b725..761807213d2 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5502,7 +5502,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, ) { - match (&expected.kind, &found.kind) { + let (sig, did, substs) = match (&expected.kind, &found.kind) { (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => { let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1); let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2); @@ -5513,29 +5513,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "different `fn` items always have unique types, even if their signatures are \ the same", ); - err.help(&format!("change the expectation to require function pointer `{}`", sig1)); - err.help(&format!( - "if the expectation is due to type inference, cast the expected `fn` to a \ - function pointer: `{} as {}`", - self.tcx.def_path_str_with_substs(*did1, substs1), - sig1 - )); + (sig1, *did1, substs1) } (ty::FnDef(did, substs), ty::FnPtr(sig2)) => { let sig1 = self.tcx.fn_sig(*did).subst(self.tcx, substs); if sig1 != *sig2 { return; } - err.help(&format!("change the expectation to require function pointer `{}`", sig1)); - err.help(&format!( - "if the expectation is due to type inference, cast the expected `fn` to a \ - function pointer: `{} as {}`", - self.tcx.def_path_str_with_substs(*did, substs), - sig1 - )); + (sig1, *did, substs) } - _ => {} - } + _ => return, + }; + err.help(&format!("change the expected type to be function pointer `{}`", sig)); + err.help(&format!( + "if the expected type is due to type inference, cast the expected `fn` to a function \ + pointer: `{} as {}`", + self.tcx.def_path_str_with_substs(did, substs), + sig + )); } /// A common error is to add an extra semicolon: diff --git a/src/test/ui/fn/fn-item-type.rs b/src/test/ui/fn/fn-item-type.rs index 256b9d45755..abae40162a0 100644 --- a/src/test/ui/fn/fn-item-type.rs +++ b/src/test/ui/fn/fn-item-type.rs @@ -16,15 +16,15 @@ fn main() { //~| found fn item `fn(_) -> _ {bar::}` //~| expected fn item, found a different fn item //~| different `fn` items always have unique types, even if their signatures are the same - //~| change the expectation to require function pointer - //~| if the expectation is due to type inference, cast the expected `fn` to a function pointer + //~| change the expected type to be function pointer + //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer eq(foo::, foo::); //~^ ERROR mismatched types //~| expected `u8`, found `i8` //~| different `fn` items always have unique types, even if their signatures are the same - //~| change the expectation to require function pointer - //~| if the expectation is due to type inference, cast the expected `fn` to a function pointer + //~| change the expected type to be function pointer + //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer eq(bar::, bar::>); //~^ ERROR mismatched types @@ -32,24 +32,24 @@ fn main() { //~| found fn item `fn(_) -> _ {bar::>}` //~| expected struct `std::string::String`, found struct `std::vec::Vec` //~| different `fn` items always have unique types, even if their signatures are the same - //~| change the expectation to require function pointer - //~| if the expectation is due to type inference, cast the expected `fn` to a function pointer + //~| change the expected type to be function pointer + //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer // Make sure we distinguish between trait methods correctly. eq(::foo, ::foo); //~^ ERROR mismatched types //~| expected `u8`, found `u16` //~| different `fn` items always have unique types, even if their signatures are the same - //~| change the expectation to require function pointer - //~| if the expectation is due to type inference, cast the expected `fn` to a function pointer + //~| change the expected type to be function pointer + //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer eq(foo::, bar:: as fn(isize) -> isize); //~^ ERROR mismatched types //~| expected fn item `fn(_) -> _ {foo::}` //~| found fn pointer `fn(_) -> _` //~| expected fn item, found fn pointer - //~| change the expectation to require function pointer - //~| if the expectation is due to type inference, cast the expected `fn` to a function pointer + //~| change the expected type to be function pointer + //~| if the expected type is due to type inference, cast the expected `fn` to a function pointer eq(foo:: as fn(isize) -> isize, bar::); // ok! } diff --git a/src/test/ui/fn/fn-item-type.stderr b/src/test/ui/fn/fn-item-type.stderr index 84f5e034340..bfa9efa219f 100644 --- a/src/test/ui/fn/fn-item-type.stderr +++ b/src/test/ui/fn/fn-item-type.stderr @@ -7,8 +7,8 @@ LL | eq(foo::, bar::); = note: expected fn item `fn(_) -> _ {foo::}` found fn item `fn(_) -> _ {bar::}` = note: different `fn` items always have unique types, even if their signatures are the same - = help: change the expectation to require function pointer `fn(isize) -> isize` - = help: if the expectation is due to type inference, cast the expected `fn` to a function pointer: `foo:: as fn(isize) -> isize` + = help: change the expected type to be function pointer `fn(isize) -> isize` + = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo:: as fn(isize) -> isize` error[E0308]: mismatched types --> $DIR/fn-item-type.rs:22:19 @@ -19,8 +19,8 @@ LL | eq(foo::, foo::); = note: expected fn item `fn(_) -> _ {foo::}` found fn item `fn(_) -> _ {foo::}` = note: different `fn` items always have unique types, even if their signatures are the same - = help: change the expectation to require function pointer `fn(isize) -> isize` - = help: if the expectation is due to type inference, cast the expected `fn` to a function pointer: `foo:: as fn(isize) -> isize` + = help: change the expected type to be function pointer `fn(isize) -> isize` + = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo:: as fn(isize) -> isize` error[E0308]: mismatched types --> $DIR/fn-item-type.rs:29:23 @@ -31,8 +31,8 @@ LL | eq(bar::, bar::>); = note: expected fn item `fn(_) -> _ {bar::}` found fn item `fn(_) -> _ {bar::>}` = note: different `fn` items always have unique types, even if their signatures are the same - = help: change the expectation to require function pointer `fn(isize) -> isize` - = help: if the expectation is due to type inference, cast the expected `fn` to a function pointer: `bar:: as fn(isize) -> isize` + = help: change the expected type to be function pointer `fn(isize) -> isize` + = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `bar:: as fn(isize) -> isize` error[E0308]: mismatched types --> $DIR/fn-item-type.rs:39:26 @@ -43,8 +43,8 @@ LL | eq(::foo, ::foo); = note: expected fn item `fn() {::foo}` found fn item `fn() {::foo}` = note: different `fn` items always have unique types, even if their signatures are the same - = help: change the expectation to require function pointer `fn()` - = help: if the expectation is due to type inference, cast the expected `fn` to a function pointer: `::foo as fn()` + = help: change the expected type to be function pointer `fn()` + = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `::foo as fn()` error[E0308]: mismatched types --> $DIR/fn-item-type.rs:46:19 @@ -54,8 +54,8 @@ LL | eq(foo::, bar:: as fn(isize) -> isize); | = note: expected fn item `fn(_) -> _ {foo::}` found fn pointer `fn(_) -> _` - = help: change the expectation to require function pointer `fn(isize) -> isize` - = help: if the expectation is due to type inference, cast the expected `fn` to a function pointer: `foo:: as fn(isize) -> isize` + = help: change the expected type to be function pointer `fn(isize) -> isize` + = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo:: as fn(isize) -> isize` error: aborting due to 5 previous errors