Deduplicate fn trait compatibility checks

This commit is contained in:
Oli Scherer 2023-03-21 11:38:13 +00:00
parent fb9e171ab7
commit 91d913168c
3 changed files with 21 additions and 29 deletions

View File

@ -23,7 +23,7 @@
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span; use rustc_span::Span;
use rustc_target::abi::VariantIdx; use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi; use rustc_target::spec::abi::{self, Abi};
use std::borrow::Cow; use std::borrow::Cow;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::fmt; use std::fmt;
@ -1403,6 +1403,18 @@ pub fn unsafety(&self) -> hir::Unsafety {
pub fn abi(&self) -> abi::Abi { pub fn abi(&self) -> abi::Abi {
self.skip_binder().abi self.skip_binder().abi
} }
pub fn is_fn_trait_compatible(&self) -> bool {
matches!(
self.skip_binder(),
ty::FnSig {
unsafety: rustc_hir::Unsafety::Normal,
abi: Abi::Rust,
c_variadic: false,
..
}
)
}
} }
pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>; pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>;

View File

@ -2,7 +2,6 @@
use rustc_hir::{def_id::DefId, Movability, Mutability}; use rustc_hir::{def_id::DefId, Movability, Mutability};
use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::query::NoSolution;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_target::spec::abi::Abi;
use crate::solve::EvalCtxt; use crate::solve::EvalCtxt;
@ -197,13 +196,7 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
)), )),
// keep this in sync with assemble_fn_pointer_candidates until the old solver is removed. // keep this in sync with assemble_fn_pointer_candidates until the old solver is removed.
ty::FnPtr(sig) => { ty::FnPtr(sig) => {
if let ty::FnSig { if sig.is_fn_trait_compatible() {
unsafety: rustc_hir::Unsafety::Normal,
abi: Abi::Rust,
c_variadic: false,
..
} = sig.skip_binder()
{
Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())))) Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output()))))
} else { } else {
Err(NoSolution) Err(NoSolution)

View File

@ -11,7 +11,6 @@
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
use rustc_middle::ty::fast_reject::TreatProjections; use rustc_middle::ty::fast_reject::TreatProjections;
use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_target::spec::abi::Abi;
use crate::traits; use crate::traits;
use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::query::evaluate_obligation::InferCtxtExt;
@ -302,33 +301,21 @@ fn assemble_fn_pointer_candidates(
candidates.ambiguous = true; // Could wind up being a fn() type. candidates.ambiguous = true; // Could wind up being a fn() type.
} }
// Provide an impl, but only for suitable `fn` pointers. // Provide an impl, but only for suitable `fn` pointers.
ty::FnPtr(_) => { ty::FnPtr(sig) => {
if let ty::FnSig { if sig.is_fn_trait_compatible() {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
c_variadic: false,
..
} = self_ty.fn_sig(self.tcx()).skip_binder()
{
candidates.vec.push(FnPointerCandidate { is_const: false }); candidates.vec.push(FnPointerCandidate { is_const: false });
} }
} }
// Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396). // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
ty::FnDef(def_id, _) => { ty::FnDef(def_id, _) => {
if let ty::FnSig { if self.tcx().fn_sig(def_id).skip_binder().is_fn_trait_compatible()
unsafety: hir::Unsafety::Normal, && self.tcx().codegen_fn_attrs(def_id).target_features.is_empty()
abi: Abi::Rust,
c_variadic: false,
..
} = self_ty.fn_sig(self.tcx()).skip_binder()
{ {
if self.tcx().codegen_fn_attrs(def_id).target_features.is_empty() {
candidates candidates
.vec .vec
.push(FnPointerCandidate { is_const: self.tcx().is_const_fn(def_id) }); .push(FnPointerCandidate { is_const: self.tcx().is_const_fn(def_id) });
} }
} }
}
_ => {} _ => {}
} }
} }