use crate::{
autoderef, method_resolution, op,
- traits::{builtin::get_fn_trait, FnTrait, InEnvironment, SolutionVariables},
+ traits::{FnTrait, InEnvironment, SolutionVariables},
utils::{generics, variant_data, Generics},
ApplicationTy, Binders, CallableDef, FnSig, InferTy, IntTy, Mutability, Obligation, Rawness,
Substs, TraitRef, Ty, TypeCtor,
if let Some(krate) = self.resolver.krate() {
let fn_traits: Vec<crate::TraitId> = [FnTrait::FnOnce, FnTrait::FnMut, FnTrait::Fn]
.iter()
- .filter_map(|f| get_fn_trait(self.db, krate, *f))
+ .filter_map(|f| f.get_id(self.db, krate))
.collect();
for fn_trait in fn_traits {
let fn_trait_data = self.db.trait_data(fn_trait);
use std::{panic, sync::Arc};
use chalk_ir::cast::Cast;
-use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId};
+use hir_def::{
+ expr::ExprId, lang_item::LangItemTarget, DefWithBodyId, ImplId, TraitId, TypeAliasId,
+};
use ra_db::{impl_intern_key, salsa, CrateId};
use ra_prof::profile;
use rustc_hash::FxHashSet;
use self::chalk::{from_chalk, Interner, ToChalk};
pub(crate) mod chalk;
-pub(crate) mod builtin;
+mod builtin;
// This controls the maximum size of types Chalk considers. If we set this too
// high, we can run into slow edge cases; if we set it too low, Chalk won't
FnTrait::Fn => "fn",
}
}
+
+ pub fn get_id(&self, db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> {
+ let target = db.lang_item(krate, self.lang_item_name().into())?;
+ match target {
+ LangItemTarget::TraitId(t) => Some(t),
+ _ => None,
+ }
+ }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty {
for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter()
{
- if let Some(actual_trait) = get_fn_trait(db, krate, fn_trait) {
+ if let Some(actual_trait) = fn_trait.get_id(db, krate) {
if trait_ == actual_trait {
let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait };
if check_closure_fn_trait_impl_prerequisites(db, krate, impl_) {
data: super::ClosureFnTraitImplData,
) -> bool {
// the respective Fn/FnOnce/FnMut trait needs to exist
- if get_fn_trait(db, krate, data.fn_trait).is_none() {
+ if data.fn_trait.get_id(db, krate).is_none() {
return false;
}
// the traits having no type params, FnOnce being a supertrait
// the FnOnce trait needs to exist and have an assoc type named Output
- let fn_once_trait = match get_fn_trait(db, krate, super::FnTrait::FnOnce) {
+ let fn_once_trait = match (super::FnTrait::FnOnce).get_id(db, krate) {
Some(t) => t,
None => return false,
};
// for some closure |X, Y| -> Z:
// impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V }
- let trait_ = get_fn_trait(db, krate, data.fn_trait) // get corresponding fn trait
+ let trait_ = data
+ .fn_trait
+ .get_id(db, krate) // get corresponding fn trait
// the existence of the Fn trait has been checked before
.expect("fn trait for closure impl missing");
let output_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, num_args.into()));
let fn_once_trait =
- get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist");
+ (super::FnTrait::FnOnce).get_id(db, krate).expect("assoc ty value should not exist");
let output_ty_id = db
.trait_data(fn_once_trait)
BuiltinImplData { num_vars, trait_ref, where_clauses: Vec::new(), assoc_ty_values: Vec::new() }
}
-pub fn get_fn_trait(
- db: &dyn HirDatabase,
- krate: CrateId,
- fn_trait: super::FnTrait,
-) -> Option<TraitId> {
- let target = db.lang_item(krate, fn_trait.lang_item_name().into())?;
- match target {
- LangItemTarget::TraitId(t) => Some(t),
- _ => None,
- }
-}
-
fn get_unsize_trait(db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> {
let target = db.lang_item(krate, "unsize".into())?;
match target {