Rollup merge of #100473 - compiler-errors:normalize-the-fn-def-sig-plz, r=lcnr
Attempt to normalize `FnDef` signature in `InferCtxt::cmp` Stashes a normalization callback in `InferCtxt` so that the signature we get from `tcx.fn_sig(..).subst(..)` in `InferCtxt::cmp` can be properly normalized, since we cannot expect for it to have normalized types since it comes straight from astconv. This is kind of a hack, but I will say that `@jyn514` found the fact that we present unnormalized types to be very confusing in real life code, and I agree with that feeling. Though altogether I am still a bit unsure about whether this PR is worth the effort, so I'm open to alternatives and/or just closing it outright. On the other hand, this isn't a ridiculously heavy implementation anyways -- it's less than a hundred lines of changes, and half of that is just miscellaneous cleanup. This is stacked onto #100471 which is basically unrelated, and it can be rebased off of that when that lands or if needed. --- The code: ```rust trait Foo { type Bar; } impl<T> Foo for T { type Bar = i32; } fn foo<T>(_: <T as Foo>::Bar) {} fn needs_i32_ref_fn(f: fn(&'static i32)) {} fn main() { needs_i32_ref_fn(foo::<()>); } ``` Before: ``` = note: expected fn pointer `fn(&'static i32)` found fn item `fn(<() as Foo>::Bar) {foo::<()>}` ``` After: ``` = note: expected fn pointer `fn(&'static i32)` found fn item `fn(i32) {foo::<()>}` ```
This commit is contained in:
commit
15e2e5185a
8 changed files with 125 additions and 14 deletions
|
@ -1,6 +1,7 @@
|
|||
use super::callee::DeferredCallResolution;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::HirIdMap;
|
||||
|
@ -12,7 +13,9 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
|
|||
use rustc_span::def_id::LocalDefIdMap;
|
||||
use rustc_span::{self, Span};
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{self, ObligationCause, TraitEngine, TraitEngineExt};
|
||||
use rustc_trait_selection::traits::{
|
||||
self, ObligationCause, ObligationCtxt, TraitEngine, TraitEngineExt as _,
|
||||
};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ops::Deref;
|
||||
|
@ -84,7 +87,29 @@ impl<'tcx> Inherited<'_, 'tcx> {
|
|||
infcx: tcx
|
||||
.infer_ctxt()
|
||||
.ignoring_regions()
|
||||
.with_fresh_in_progress_typeck_results(hir_owner),
|
||||
.with_fresh_in_progress_typeck_results(hir_owner)
|
||||
.with_normalize_fn_sig_for_diagnostic(Lrc::new(move |infcx, fn_sig| {
|
||||
if fn_sig.has_escaping_bound_vars() {
|
||||
return fn_sig;
|
||||
}
|
||||
infcx.probe(|_| {
|
||||
let ocx = ObligationCtxt::new_in_snapshot(infcx);
|
||||
let normalized_fn_sig = ocx.normalize(
|
||||
ObligationCause::dummy(),
|
||||
// FIXME(compiler-errors): This is probably not the right param-env...
|
||||
infcx.tcx.param_env(def_id),
|
||||
fn_sig,
|
||||
);
|
||||
if ocx.select_all_or_error().is_empty() {
|
||||
let normalized_fn_sig =
|
||||
infcx.resolve_vars_if_possible(normalized_fn_sig);
|
||||
if !normalized_fn_sig.needs_infer() {
|
||||
return normalized_fn_sig;
|
||||
}
|
||||
}
|
||||
fn_sig
|
||||
})
|
||||
})),
|
||||
def_id,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue