Rollup merge of #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 https://github.com/rust-lang/rust/pull/115897#discussion_r1331940846
This commit is contained in:
Matthias Krüger 2023-09-24 01:14:05 +02:00 committed by GitHub
commit d92a1bd7cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 48 additions and 27 deletions

View File

@ -1134,7 +1134,10 @@ fn report_trait_method_mismatch<'tcx>(
&mut diag, &mut diag,
&cause, &cause,
trait_err_span.map(|sp| (sp, Cow::from("type in trait"))), trait_err_span.map(|sp| (sp, Cow::from("type in trait"))),
Some(infer::ValuePairs::Sigs(ExpectedFound { expected: trait_sig, found: impl_sig })), Some(infer::ValuePairs::PolySigs(ExpectedFound {
expected: ty::Binder::dummy(trait_sig),
found: ty::Binder::dummy(impl_sig),
})),
terr, terr,
false, false,
false, false,

View File

@ -573,10 +573,7 @@ pub fn check_function_signature<'tcx>(
let norm_cause = ObligationCause::misc(cause.span, local_id); let norm_cause = ObligationCause::misc(cause.span, local_id);
let actual_sig = ocx.normalize(&norm_cause, param_env, actual_sig); let actual_sig = ocx.normalize(&norm_cause, param_env, actual_sig);
let expected_ty = Ty::new_fn_ptr(tcx, expected_sig); match ocx.eq(&cause, param_env, expected_sig, actual_sig) {
let actual_ty = Ty::new_fn_ptr(tcx, actual_sig);
match ocx.eq(&cause, param_env, expected_ty, actual_ty) {
Ok(()) => { Ok(()) => {
let errors = ocx.select_all_or_error(); let errors = ocx.select_all_or_error();
if !errors.is_empty() { if !errors.is_empty() {
@ -595,9 +592,9 @@ pub fn check_function_signature<'tcx>(
&mut diag, &mut diag,
&cause, &cause,
None, None,
Some(infer::ValuePairs::Sigs(ExpectedFound { Some(infer::ValuePairs::PolySigs(ExpectedFound {
expected: tcx.liberate_late_bound_regions(fn_id, expected_sig), expected: expected_sig,
found: tcx.liberate_late_bound_regions(fn_id, actual_sig), found: actual_sig,
})), })),
err, err,
false, false,

View File

@ -478,7 +478,28 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
a: Self, a: Self,
b: Self, b: Self,
) -> TypeTrace<'tcx> { ) -> TypeTrace<'tcx> {
TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) } TypeTrace {
cause: cause.clone(),
values: PolySigs(ExpectedFound::new(
a_is_expected,
ty::Binder::dummy(a),
ty::Binder::dummy(b),
)),
}
}
}
impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
fn to_trace(
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
a: Self,
b: Self,
) -> TypeTrace<'tcx> {
TypeTrace {
cause: cause.clone(),
values: PolySigs(ExpectedFound::new(a_is_expected, a, b)),
}
} }
} }

View File

@ -1660,7 +1660,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
_ => (false, Mismatch::Fixed("type")), _ => (false, Mismatch::Fixed("type")),
} }
} }
ValuePairs::Sigs(infer::ExpectedFound { expected, found }) => { ValuePairs::PolySigs(infer::ExpectedFound { expected, found }) => {
OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span) OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
.report(diag); .report(diag);
(false, Mismatch::Fixed("signature")) (false, Mismatch::Fixed("signature"))
@ -2232,15 +2232,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ret => ret, ret => ret,
} }
} }
infer::Sigs(exp_found) => { infer::PolySigs(exp_found) => {
let exp_found = self.resolve_vars_if_possible(exp_found); let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() { if exp_found.references_error() {
return None; return None;
} }
let (exp, fnd) = self.cmp_fn_sig( let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
&ty::Binder::dummy(exp_found.expected),
&ty::Binder::dummy(exp_found.found),
);
Some((exp, fnd, None, None)) Some((exp, fnd, None, None))
} }
} }

View File

@ -35,14 +35,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
&& let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin) && let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
&& let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code() && let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
&& sub_trace.values == sup_trace.values && sub_trace.values == sup_trace.values
&& let ValuePairs::Sigs(ExpectedFound { expected, found }) = sub_trace.values && let ValuePairs::PolySigs(ExpectedFound { expected, found }) = sub_trace.values
{ {
// FIXME(compiler-errors): Don't like that this needs `Ty`s, but // FIXME(compiler-errors): Don't like that this needs `Ty`s, but
// all of the region highlighting machinery only deals with those. // all of the region highlighting machinery only deals with those.
let guar = self.emit_err( let guar = self.emit_err(
var_origin.span(), var_origin.span(),
Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(expected)), Ty::new_fn_ptr(self.cx.tcx, expected),
Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(found)), Ty::new_fn_ptr(self.cx.tcx, found),
*trait_item_def_id, *trait_item_def_id,
); );
return Some(guar); return Some(guar);

View File

@ -383,7 +383,7 @@ pub enum ValuePairs<'tcx> {
Aliases(ExpectedFound<ty::AliasTy<'tcx>>), Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>), TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>), PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
Sigs(ExpectedFound<ty::FnSig<'tcx>>), PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>), ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
ExistentialProjection(ExpectedFound<ty::PolyExistentialProjection<'tcx>>), ExistentialProjection(ExpectedFound<ty::PolyExistentialProjection<'tcx>>),
} }

View File

@ -2333,7 +2333,10 @@ impl CheckAttrVisitor<'_> {
&mut diag, &mut diag,
&cause, &cause,
None, None,
Some(ValuePairs::Sigs(ExpectedFound { expected: expected_sig, found: sig })), Some(ValuePairs::PolySigs(ExpectedFound {
expected: ty::Binder::dummy(expected_sig),
found: ty::Binder::dummy(sig),
})),
terr, terr,
false, false,
false, false,

View File

@ -4,8 +4,8 @@ error[E0308]: `#[panic_handler]` function has wrong type
LL | fn panic(info: PanicInfo) -> () {} LL | fn panic(info: PanicInfo) -> () {}
| ^^^^^^^^^ expected `&PanicInfo<'_>`, found `PanicInfo<'_>` | ^^^^^^^^^ expected `&PanicInfo<'_>`, found `PanicInfo<'_>`
| |
= note: expected signature `fn(&PanicInfo<'_>) -> !` = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
found signature `fn(PanicInfo<'_>)` found signature `for<'a> fn(PanicInfo<'a>)`
error: aborting due to previous error error: aborting due to previous error

View File

@ -4,8 +4,8 @@ error[E0308]: `#[panic_handler]` function has wrong type
LL | fn panic(info: &'static PanicInfo) -> ! LL | fn panic(info: &'static PanicInfo) -> !
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
| |
= note: expected fn pointer `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _`
found fn pointer `for<'a> fn(&'static PanicInfo<'a>) -> _` found signature `for<'a> fn(&'static PanicInfo<'a>) -> _`
error: aborting due to previous error error: aborting due to previous error

View File

@ -4,7 +4,7 @@ error[E0308]: `#[panic_handler]` function has wrong type
LL | fn panic() -> ! { LL | fn panic() -> ! {
| ^^^^^^^^^^^^^^^ incorrect number of function parameters | ^^^^^^^^^^^^^^^ incorrect number of function parameters
| |
= note: expected signature `fn(&PanicInfo<'_>) -> _` = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _`
found signature `fn() -> _` found signature `fn() -> _`
error: aborting due to previous error error: aborting due to previous error

View File

@ -4,8 +4,8 @@ error[E0308]: `#[panic_handler]` function has wrong type
LL | fn panic(info: &PanicInfo<'static>) -> ! LL | fn panic(info: &PanicInfo<'static>) -> !
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
| |
= note: expected fn pointer `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _`
found fn pointer `for<'a> fn(&'a PanicInfo<'static>) -> _` found signature `for<'a> fn(&'a PanicInfo<'static>) -> _`
error: aborting due to previous error error: aborting due to previous error