mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-06 08:36:52 -04:00
Rollup merge of #156058 - qaijuang:issue-151393, r=JohnTitor
Print HRTB binders before fn qualifiers Fixes rust-lang/rust#151393 This PR updates the custom fn-signature diff used in type mismatch diagnostics to print higher-ranked binders before fn qualifiers. We might want to update reference also: https://github.com/rust-lang/reference/blob/581920f9109f141b88b860b3e1e8359e3896a150/src/items/external-blocks.md?plain=1#L60
This commit is contained in:
@@ -779,29 +779,40 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
let (lt1, sig1) = get_lifetimes(sig1);
|
||||
let (lt2, sig2) = get_lifetimes(sig2);
|
||||
|
||||
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
|
||||
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
|
||||
let mut values =
|
||||
(DiagStyledString::normal("".to_string()), DiagStyledString::normal("".to_string()));
|
||||
|
||||
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
|
||||
// ^^^^^^
|
||||
let safety = |fn_def, sig: ty::FnSig<'_>| match fn_def {
|
||||
None => sig.safety().prefix_str(),
|
||||
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
|
||||
// ^^^^^^^^^^^^^^^^^^
|
||||
let fn_item_prefix_and_safety = |fn_def, sig: ty::FnSig<'_>| match fn_def {
|
||||
None => ("", sig.safety().prefix_str()),
|
||||
Some((did, _)) => {
|
||||
if self.tcx.codegen_fn_attrs(did).safe_target_features {
|
||||
"#[target_features] "
|
||||
("#[target_features] ", "")
|
||||
} else {
|
||||
sig.safety().prefix_str()
|
||||
("", sig.safety().prefix_str())
|
||||
}
|
||||
}
|
||||
};
|
||||
let safety1 = safety(fn_def1, sig1);
|
||||
let safety2 = safety(fn_def2, sig2);
|
||||
let (prefix1, safety1) = fn_item_prefix_and_safety(fn_def1, sig1);
|
||||
let (prefix2, safety2) = fn_item_prefix_and_safety(fn_def2, sig2);
|
||||
values.0.push(prefix1, prefix1 != prefix2);
|
||||
values.1.push(prefix2, prefix1 != prefix2);
|
||||
|
||||
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
|
||||
// ^^^^^^^^
|
||||
let lifetime_diff = lt1 != lt2;
|
||||
values.0.push(lt1, lifetime_diff);
|
||||
values.1.push(lt2, lifetime_diff);
|
||||
|
||||
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
|
||||
// ^^^^^^
|
||||
values.0.push(safety1, safety1 != safety2);
|
||||
values.1.push(safety2, safety1 != safety2);
|
||||
|
||||
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
|
||||
// ^^^^^^^^^^
|
||||
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
|
||||
// ^^^^^^^^^^
|
||||
if sig1.abi() != ExternAbi::Rust {
|
||||
values.0.push(format!("extern {} ", sig1.abi()), sig1.abi() != sig2.abi());
|
||||
}
|
||||
@@ -809,19 +820,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
values.1.push(format!("extern {} ", sig2.abi()), sig1.abi() != sig2.abi());
|
||||
}
|
||||
|
||||
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
|
||||
// ^^^^^^^^
|
||||
let lifetime_diff = lt1 != lt2;
|
||||
values.0.push(lt1, lifetime_diff);
|
||||
values.1.push(lt2, lifetime_diff);
|
||||
|
||||
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
|
||||
// ^^^
|
||||
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
|
||||
// ^^^
|
||||
values.0.push_normal("fn(");
|
||||
values.1.push_normal("fn(");
|
||||
|
||||
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
|
||||
// ^^^^^
|
||||
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
|
||||
// ^^^^^
|
||||
let len1 = sig1.inputs().len();
|
||||
let len2 = sig2.inputs().len();
|
||||
if len1 == len2 {
|
||||
@@ -859,13 +864,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
values.1.push("...", !sig1.c_variadic());
|
||||
}
|
||||
|
||||
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
|
||||
// ^
|
||||
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
|
||||
// ^
|
||||
values.0.push_normal(")");
|
||||
values.1.push_normal(")");
|
||||
|
||||
// unsafe extern "C" for<'a> fn(&'a T) -> &'a T
|
||||
// ^^^^^^^^
|
||||
// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
|
||||
// ^^^^^^^^
|
||||
let output1 = sig1.output();
|
||||
let output2 = sig2.output();
|
||||
let (x1, x2) = self.cmp(output1, output2);
|
||||
|
||||
@@ -10,7 +10,19 @@ fn foo(x: i32) -> u32 {
|
||||
0
|
||||
}
|
||||
|
||||
extern "C" fn extern_foo(_: &i32) {}
|
||||
|
||||
unsafe extern "C" fn unsafe_extern_foo(_: &i32) {}
|
||||
|
||||
fn rust_foo(_: &i32) {}
|
||||
|
||||
fn main() {
|
||||
let b: fn() -> u32 = bar; //~ ERROR mismatched types [E0308]
|
||||
let f: fn(i32) = foo; //~ ERROR mismatched types [E0308]
|
||||
|
||||
// See https://github.com/rust-lang/rust/issues/151393
|
||||
let _: for<'a> fn(&'a i32) = extern_foo; //~ ERROR mismatched types [E0308]
|
||||
let _: for<'a> fn(&'a i32) = unsafe_extern_foo; //~ ERROR mismatched types [E0308]
|
||||
let _: for<'a> extern "C" fn(&'a i32) = rust_foo; //~ ERROR mismatched types [E0308]
|
||||
let _: for<'a> unsafe extern "C" fn(&'a i32) = rust_foo; //~ ERROR mismatched types [E0308]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-pointer-mismatch-diagnostics.rs:14:26
|
||||
--> $DIR/fn-pointer-mismatch-diagnostics.rs:20:26
|
||||
|
|
||||
LL | let b: fn() -> u32 = bar;
|
||||
| ----------- ^^^ expected fn pointer, found fn item
|
||||
@@ -10,7 +10,7 @@ LL | let b: fn() -> u32 = bar;
|
||||
found fn item `fn() -> () {bar}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-pointer-mismatch-diagnostics.rs:15:22
|
||||
--> $DIR/fn-pointer-mismatch-diagnostics.rs:21:22
|
||||
|
|
||||
LL | let f: fn(i32) = foo;
|
||||
| ------- ^^^ expected fn pointer, found fn item
|
||||
@@ -20,6 +20,51 @@ LL | let f: fn(i32) = foo;
|
||||
= note: expected fn pointer `fn(_) -> ()`
|
||||
found fn item `fn(_) -> u32 {foo}`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-pointer-mismatch-diagnostics.rs:24:34
|
||||
|
|
||||
LL | let _: for<'a> fn(&'a i32) = extern_foo;
|
||||
| ------------------- ^^^^^^^^^^ expected "Rust" fn, found "C" fn
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected fn pointer `for<'a> fn(&'a _)`
|
||||
found fn item `for<'a> extern "C" fn(&'a _) {extern_foo}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-pointer-mismatch-diagnostics.rs:25:34
|
||||
|
|
||||
LL | let _: for<'a> fn(&'a i32) = unsafe_extern_foo;
|
||||
| ------------------- ^^^^^^^^^^^^^^^^^ expected safe fn, found unsafe fn
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected fn pointer `for<'a> fn(&'a _)`
|
||||
found fn item `for<'a> unsafe extern "C" fn(&'a _) {unsafe_extern_foo}`
|
||||
= note: unsafe functions cannot be coerced into safe function pointers
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-pointer-mismatch-diagnostics.rs:26:45
|
||||
|
|
||||
LL | let _: for<'a> extern "C" fn(&'a i32) = rust_foo;
|
||||
| ------------------------------ ^^^^^^^^ expected "C" fn, found "Rust" fn
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected fn pointer `for<'a> extern "C" fn(&'a _)`
|
||||
found fn item `for<'a> fn(&'a _) {rust_foo}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-pointer-mismatch-diagnostics.rs:27:52
|
||||
|
|
||||
LL | let _: for<'a> unsafe extern "C" fn(&'a i32) = rust_foo;
|
||||
| ------------------------------------- ^^^^^^^^ expected "C" fn, found "Rust" fn
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected fn pointer `for<'a> unsafe extern "C" fn(&'a _)`
|
||||
found fn item `for<'a> fn(&'a _) {rust_foo}`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
||||
Reference in New Issue
Block a user