Deduplicate fn trait compatibility checks
This commit is contained in:
parent
fb9e171ab7
commit
91d913168c
@ -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>>>;
|
||||||
|
@ -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)
|
||||||
|
@ -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) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user