-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
rustc_hir_analysis: add a helper to check function the signature mismatches #115897
Conversation
r? @jackh726 (rustbot has picked a reviewer for you, use r? to override) |
| | ||
= note: expected signature `fn(&PanicInfo<'_>) -> _` | ||
found signature `fn(&'static PanicInfo<'_>) -> _` | ||
note: the anonymous lifetime as defined here... |
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.
This is pretty confusing. We probably want to actually replace the call to ocx.resolve_regions_and_report_errors
to a manual call to ocx.infcx.resolve_regions
and report any region errors manually from there with a more descriptive message.
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.
What message would we want here?
In the case of a trait/impl:
use std::panic::PanicInfo;
trait Tr {
fn panic(info: &PanicInfo<'_>);
}
impl Tr for () {
fn panic(_info: &'static PanicInfo) {
unimplemented!();
}
}
It is reported similarly:
error[E0308]: method not compatible with trait
--> lib.rs:8:5
|
8 | fn panic(_info: &'static PanicInfo) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected signature `fn(&PanicInfo<'_>)`
found signature `fn(&'static PanicInfo<'_>)`
note: the anonymous lifetime as defined here...
--> lib.rs:8:30
|
8 | fn panic(_info: &'static PanicInfo) {
| ^^^^^^^^^
= note: ...does not necessarily outlive the static lifetime
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
The difference is that in the test, the note spans the whole signature instead of just PanicInfo
:
note: the anonymous lifetime as defined here...
--> $DIR/panic-handler-bad-signature-2.rs:9:1
|
LL | fn panic(info: &'static PanicInfo) -> !
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...does not necessarily outlive the static lifetime
I'm not sure why.
EDIT: I think it depends on whether the region is BrAnon
or BrNamed
with kw::UnderscoreLifetime
.
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.
I opened #115903 regarding confusing lifetime diagnosis for trait impl functions. I think fixing that its outside the scope of this PR.
pub fn check_function_signature<'tcx>( | ||
tcx: TyCtxt<'tcx>, | ||
cause_code: ObligationCauseCode<'tcx>, | ||
fn_id: LocalDefId, |
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.
This can be a DefId
, and you can use CRATE_DEF_ID
for the cases that it's required to be a LocalDefId
.
|
||
pub fn check_function_signature<'tcx>( | ||
tcx: TyCtxt<'tcx>, | ||
cause_code: ObligationCauseCode<'tcx>, |
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.
Can you make the caller pass in a full ObligationCause
? That's usually more conventional than just passing the code.
|
||
let expected_sig = tcx.liberate_late_bound_regions(fn_id.into(), expected_sig); | ||
|
||
match ocx.sup(&cause, param_env, expected_sig, actual_sig) { |
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.
It concerns me that we're only checking the subtyping in one direction instead of both directions (with eq
) here.
We should ideally be instantiating the binder in both directions -- this should cause us to accept more code, possibly inadvertently?
@rustbot ready |
☔ The latest upstream changes (presumably #115909) made this pull request unmergeable. Please resolve the merge conflicts. |
4576ad4
to
3a4242c
Compare
|
||
let expected_sig = tcx.liberate_late_bound_regions(fn_id, expected_sig); | ||
|
||
match ocx.eq(&cause, param_env, expected_sig, actual_sig) { |
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.
This is not how to compare two binders. This is not very much different than using sub
, which I think is still wrong. You should probably wrap both binders in a FnPtr
and compare them directly. The error reporting will kinda suck, but that can be dealt with differently.
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.
The output changed from
= note: expected signature `fn(&PanicInfo<'_>) -> _`
found signature `fn(&'static PanicInfo<'_>) -> _`
to
= note: expected fn pointer `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _`
found fn pointer `for<'a> fn(&'static PanicInfo<'a>) -> _`
But only for lifetime errors.
For non-lifetime errors, it stayed expected/found signature, I believe that thanks to passing the signatures in infer::ValuePairs
here (I'm not sure that's entirely correct)
err_ctxt.note_type_err(
&mut diag,
&cause,
None,
Some(infer::ValuePairs::Sigs(ExpectedFound {
expected: tcx.liberate_late_bound_regions(fn_id, expected_sig),
found: tcx.liberate_late_bound_regions(fn_id, actual_sig),
})),
err,
false,
false,
);
☔ The latest upstream changes (presumably #115952) made this pull request unmergeable. Please resolve the merge conflicts. |
…atches This function is now used to check `#[panic_handler]`, `start` lang item, `main`, `#[start]` and intrinsic functions. The diagnosis produced are now closer to the ones produced by trait/impl method signature mismatch.
3a4242c
to
85d61b0
Compare
@bors r+ |
☀️ Test successful - checks-actions |
Finished benchmarking commit (99b63d0): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 634.138s -> 633.396s (-0.12%) |
Allow higher-ranked fn sigs in `ValuePairs` For better bookkeeping -- only affects diagnostic path. Allow reporting signature mismatches like "signature"s and not "fn pointer"s. Improves rust-lang#115897 (comment)
Allow higher-ranked fn sigs in `ValuePairs` For better bookkeeping -- only affects diagnostic path. Allow reporting signature mismatches like "signature"s and not "fn pointer"s. Improves rust-lang#115897 (comment)
Rollup merge of rust-lang#116073 - compiler-errors:poly-sigs, r=b-naber Allow higher-ranked fn sigs in `ValuePairs` For better bookkeeping -- only affects diagnostic path. Allow reporting signature mismatches like "signature"s and not "fn pointer"s. Improves rust-lang#115897 (comment)
This function is now used to check
#[panic_handler]
,start
lang item,main
,#[start]
and intrinsic functions.The diagnosis produced are now closer to the ones produced by trait/impl method signature mismatch.
This is the first time I do anything with rustc_hir_analysis/rustc_hir_typeck, so comments and suggestions about things I did wrong or that could be improved will be appreciated.