Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r--crates/hir/src/lib.rs450
1 files changed, 302 insertions, 148 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index a323f97997..027a386abe 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -20,6 +20,8 @@
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
#![recursion_limit = "512"]
+extern crate ra_ap_rustc_type_ir as rustc_type_ir;
+
mod attrs;
mod from_id;
mod has_source;
@@ -46,7 +48,7 @@ use hir_def::{
CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId,
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, SyntheticSyntax,
- TraitAliasId, TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
+ TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap},
hir::{
BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat,
@@ -54,10 +56,13 @@ use hir_def::{
},
item_tree::ImportAlias,
layout::{self, ReprOptions, TargetDataLayout},
- nameres::{self, assoc::TraitItems, diagnostics::DefDiagnostic},
+ nameres::{
+ assoc::TraitItems,
+ diagnostics::{DefDiagnostic, DefDiagnosticKind},
+ },
per_ns::PerNs,
resolver::{HasResolver, Resolver},
- signatures::{ImplFlags, StaticFlags, TraitFlags, VariantFields},
+ signatures::{ImplFlags, StaticFlags, StructFlags, TraitFlags, VariantFields},
src::HasSource as _,
visibility::visibility_from_ast,
};
@@ -67,7 +72,7 @@ use hir_expand::{
};
use hir_ty::{
AliasTy, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg,
- GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
+ GenericArgData, Interner, ParamKind, ProjectionTy, QuantifiedWhereClause, Scalar, Substitution,
TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, TyLoweringDiagnostic,
ValueTyDefId, WhereClause, all_super_traits, autoderef, check_orphan_rules,
consteval::{ConstExt, try_const_usize, unknown_const_as_generic},
@@ -76,11 +81,13 @@ use hir_ty::{
layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
method_resolution,
mir::{MutBorrowKind, interpret_mir},
+ next_solver::{
+ ClauseKind, DbInterner, GenericArgs, infer::InferCtxt, mapping::ChalkToNextSolver,
+ },
primitive::UintTy,
traits::FnTrait,
};
use itertools::Itertools;
-use nameres::diagnostics::DefDiagnosticKind;
use rustc_hash::FxHashSet;
use smallvec::SmallVec;
use span::{AstIdNode, Edition, FileId};
@@ -103,6 +110,7 @@ pub use crate::{
VisibleTraits,
},
};
+use rustc_type_ir::inherent::{IntoKind, SliceLike};
// Be careful with these re-exports.
//
@@ -117,7 +125,7 @@ pub use {
cfg::{CfgAtom, CfgExpr, CfgOptions},
hir_def::{
Complete,
- ImportPathConfig,
+ FindPathConfig,
attr::{AttrSourceMap, Attrs, AttrsWithOwner},
find_path::PrefixKind,
import_map,
@@ -187,6 +195,10 @@ pub struct CrateDependency {
}
impl Crate {
+ pub fn base(self) -> base_db::Crate {
+ self.id
+ }
+
pub fn origin(self, db: &dyn HirDatabase) -> CrateOrigin {
self.id.data(db).origin.clone()
}
@@ -320,7 +332,6 @@ pub enum ModuleDef {
Const(Const),
Static(Static),
Trait(Trait),
- TraitAlias(TraitAlias),
TypeAlias(TypeAlias),
BuiltinType(BuiltinType),
Macro(Macro),
@@ -333,7 +344,6 @@ impl_from!(
Const,
Static,
Trait,
- TraitAlias,
TypeAlias,
BuiltinType,
Macro
@@ -360,7 +370,6 @@ impl ModuleDef {
ModuleDef::Const(it) => Some(it.module(db)),
ModuleDef::Static(it) => Some(it.module(db)),
ModuleDef::Trait(it) => Some(it.module(db)),
- ModuleDef::TraitAlias(it) => Some(it.module(db)),
ModuleDef::TypeAlias(it) => Some(it.module(db)),
ModuleDef::Macro(it) => Some(it.module(db)),
ModuleDef::BuiltinType(_) => None,
@@ -389,7 +398,6 @@ impl ModuleDef {
ModuleDef::Const(it) => it.name(db)?,
ModuleDef::Adt(it) => it.name(db),
ModuleDef::Trait(it) => it.name(db),
- ModuleDef::TraitAlias(it) => it.name(db),
ModuleDef::Function(it) => it.name(db),
ModuleDef::Variant(it) => it.name(db),
ModuleDef::TypeAlias(it) => it.name(db),
@@ -412,7 +420,6 @@ impl ModuleDef {
Adt::Union(it) => it.id.into(),
},
ModuleDef::Trait(it) => it.id.into(),
- ModuleDef::TraitAlias(it) => it.id.into(),
ModuleDef::Function(it) => it.id.into(),
ModuleDef::TypeAlias(it) => it.id.into(),
ModuleDef::Module(it) => it.id.into(),
@@ -452,7 +459,6 @@ impl ModuleDef {
ModuleDef::Module(_)
| ModuleDef::Adt(_)
| ModuleDef::Trait(_)
- | ModuleDef::TraitAlias(_)
| ModuleDef::TypeAlias(_)
| ModuleDef::Macro(_)
| ModuleDef::BuiltinType(_) => None,
@@ -465,7 +471,6 @@ impl ModuleDef {
ModuleDef::Function(it) => Some(it.into()),
ModuleDef::Adt(it) => Some(it.into()),
ModuleDef::Trait(it) => Some(it.into()),
- ModuleDef::TraitAlias(it) => Some(it.into()),
ModuleDef::TypeAlias(it) => Some(it.into()),
ModuleDef::Module(_)
| ModuleDef::Variant(_)
@@ -485,7 +490,6 @@ impl ModuleDef {
ModuleDef::Const(it) => it.attrs(db),
ModuleDef::Static(it) => it.attrs(db),
ModuleDef::Trait(it) => it.attrs(db),
- ModuleDef::TraitAlias(it) => it.attrs(db),
ModuleDef::TypeAlias(it) => it.attrs(db),
ModuleDef::Macro(it) => it.attrs(db),
ModuleDef::BuiltinType(_) => return None,
@@ -511,7 +515,6 @@ impl HasVisibility for ModuleDef {
ModuleDef::Const(it) => it.visibility(db),
ModuleDef::Static(it) => it.visibility(db),
ModuleDef::Trait(it) => it.visibility(db),
- ModuleDef::TraitAlias(it) => it.visibility(db),
ModuleDef::TypeAlias(it) => it.visibility(db),
ModuleDef::Variant(it) => it.visibility(db),
ModuleDef::Macro(it) => it.visibility(db),
@@ -949,7 +952,7 @@ impl Module {
self,
db: &dyn DefDatabase,
item: impl Into<ItemInNs>,
- cfg: ImportPathConfig,
+ cfg: FindPathConfig,
) -> Option<ModPath> {
hir_def::find_path::find_path(
db,
@@ -968,7 +971,7 @@ impl Module {
db: &dyn DefDatabase,
item: impl Into<ItemInNs>,
prefix_kind: PrefixKind,
- cfg: ImportPathConfig,
+ cfg: FindPathConfig,
) -> Option<ModPath> {
hir_def::find_path::find_path(db, item.into().into(), self.into(), prefix_kind, true, cfg)
}
@@ -1247,6 +1250,25 @@ pub struct Field {
pub(crate) id: LocalFieldId,
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct InstantiatedField<'db> {
+ pub(crate) inner: Field,
+ pub(crate) args: GenericArgs<'db>,
+}
+
+impl<'db> InstantiatedField<'db> {
+ /// Returns the type as in the signature of the struct.
+ pub fn ty(&self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
+ let krate = self.inner.krate(db);
+ let interner = DbInterner::new_with(db, Some(krate.base()), None);
+
+ let var_id = self.inner.parent.into();
+ let field = db.field_types_ns(var_id)[self.inner.id];
+ let ty = field.instantiate(interner, self.args);
+ TypeNs::new(db, var_id, ty)
+ }
+}
+
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
pub struct TupleField {
pub owner: DefWithBodyId,
@@ -1362,8 +1384,9 @@ impl Field {
}
pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
+ let interner = DbInterner::new_with(db, None, None);
db.layout_of_ty(
- self.ty(db).ty,
+ self.ty(db).ty.to_nextsolver(interner),
db.trait_environment(match hir_def::VariantId::from(self.parent) {
hir_def::VariantId::EnumVariantId(id) => {
GenericDefId::AdtId(id.lookup(db).parent.into())
@@ -1444,6 +1467,11 @@ impl Struct {
pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
db.attrs(self.id.into()).is_unstable()
}
+
+ pub fn instantiate_infer<'db>(self, infer_ctxt: &InferCtxt<'db>) -> InstantiatedStruct<'db> {
+ let args = infer_ctxt.fresh_args_for_item(self.id.into());
+ InstantiatedStruct { inner: self, args }
+ }
}
impl HasVisibility for Struct {
@@ -1455,6 +1483,35 @@ impl HasVisibility for Struct {
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct InstantiatedStruct<'db> {
+ pub(crate) inner: Struct,
+ pub(crate) args: GenericArgs<'db>,
+}
+
+impl<'db> InstantiatedStruct<'db> {
+ pub fn fields(self, db: &dyn HirDatabase) -> Vec<InstantiatedField<'db>> {
+ self.inner
+ .id
+ .fields(db)
+ .fields()
+ .iter()
+ .map(|(id, _)| InstantiatedField {
+ inner: Field { parent: self.inner.into(), id },
+ args: self.args,
+ })
+ .collect()
+ }
+
+ pub fn ty(self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
+ let krate = self.inner.krate(db);
+ let interner = DbInterner::new_with(db, Some(krate.base()), None);
+
+ let ty = db.ty_ns(self.inner.id.into());
+ TypeNs::new(db, self.inner.id, ty.instantiate(interner, self.args))
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Union {
pub(crate) id: UnionId,
}
@@ -1598,6 +1655,22 @@ impl HasVisibility for Enum {
}
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct InstantiatedEnum<'db> {
+ pub(crate) inner: Enum,
+ pub(crate) args: GenericArgs<'db>,
+}
+
+impl<'db> InstantiatedEnum<'db> {
+ pub fn ty(self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
+ let krate = self.inner.krate(db);
+ let interner = DbInterner::new_with(db, Some(krate.base()), None);
+
+ let ty = db.ty_ns(self.inner.id.into());
+ TypeNs::new(db, self.inner.id, ty.instantiate(interner, self.args))
+ }
+}
+
impl From<&Variant> for DefWithBodyId {
fn from(&v: &Variant) -> Self {
DefWithBodyId::VariantId(v.into())
@@ -1673,6 +1746,38 @@ impl Variant {
pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
db.attrs(self.id.into()).is_unstable()
}
+
+ pub fn instantiate_infer<'db>(self, infer_ctxt: &InferCtxt<'db>) -> InstantiatedVariant<'db> {
+ let args =
+ infer_ctxt.fresh_args_for_item(self.parent_enum(infer_ctxt.interner.db()).id.into());
+ InstantiatedVariant { inner: self, args }
+ }
+}
+
+// FIXME: Rename to `EnumVariant`
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct InstantiatedVariant<'db> {
+ pub(crate) inner: Variant,
+ pub(crate) args: GenericArgs<'db>,
+}
+
+impl<'db> InstantiatedVariant<'db> {
+ pub fn parent_enum(self, db: &dyn HirDatabase) -> InstantiatedEnum<'db> {
+ InstantiatedEnum { inner: self.inner.id.lookup(db).parent.into(), args: self.args }
+ }
+
+ pub fn fields(self, db: &dyn HirDatabase) -> Vec<InstantiatedField<'db>> {
+ self.inner
+ .id
+ .fields(db)
+ .fields()
+ .iter()
+ .map(|(id, _)| InstantiatedField {
+ inner: Field { parent: self.inner.into(), id },
+ args: self.args,
+ })
+ .collect()
+ }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -1709,12 +1814,15 @@ impl Adt {
}
pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
+ let env = db.trait_environment(self.into());
+ let interner = DbInterner::new_with(db, Some(env.krate), env.block);
db.layout_of_adt(
self.into(),
TyBuilder::adt(db, self.into())
.fill_with_defaults(db, || TyKind::Error.intern(Interner))
- .build_into_subst(),
- db.trait_environment(self.into()),
+ .build_into_subst()
+ .to_nextsolver(interner),
+ env,
)
.map(|layout| Layout(layout, db.target_data_layout(self.krate(db).id).unwrap()))
}
@@ -2430,11 +2538,28 @@ impl Function {
caller: Option<Function>,
call_edition: Edition,
) -> bool {
- let target_features = caller
- .map(|caller| hir_ty::TargetFeatures::from_attrs(&db.attrs(caller.id.into())))
- .unwrap_or_default();
+ let (target_features, target_feature_is_safe_in_target) = caller
+ .map(|caller| {
+ let target_features =
+ hir_ty::TargetFeatures::from_attrs(&db.attrs(caller.id.into()));
+ let target_feature_is_safe_in_target =
+ match &caller.krate(db).id.workspace_data(db).target {
+ Ok(target) => hir_ty::target_feature_is_safe_in_target(target),
+ Err(_) => hir_ty::TargetFeatureIsSafeInTarget::No,
+ };
+ (target_features, target_feature_is_safe_in_target)
+ })
+ .unwrap_or_else(|| {
+ (hir_ty::TargetFeatures::default(), hir_ty::TargetFeatureIsSafeInTarget::No)
+ });
matches!(
- hir_ty::is_fn_unsafe_to_call(db, self.id, &target_features, call_edition),
+ hir_ty::is_fn_unsafe_to_call(
+ db,
+ self.id,
+ &target_features,
+ call_edition,
+ target_feature_is_safe_in_target
+ ),
hir_ty::Unsafety::Unsafe
)
}
@@ -2932,29 +3057,6 @@ impl HasVisibility for Trait {
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct TraitAlias {
- pub(crate) id: TraitAliasId,
-}
-
-impl TraitAlias {
- pub fn module(self, db: &dyn HirDatabase) -> Module {
- Module { id: self.id.lookup(db).container }
- }
-
- pub fn name(self, db: &dyn HirDatabase) -> Name {
- db.trait_alias_signature(self.id).name.clone()
- }
-}
-
-impl HasVisibility for TraitAlias {
- fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
- let loc = self.id.lookup(db);
- let source = loc.source(db);
- visibility_from_ast(db, self.id, source.map(|src| src.visibility()))
- }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct TypeAlias {
pub(crate) id: TypeAliasId,
}
@@ -3576,7 +3678,6 @@ pub enum GenericDef {
Function(Function),
Adt(Adt),
Trait(Trait),
- TraitAlias(TraitAlias),
TypeAlias(TypeAlias),
Impl(Impl),
// consts can have type parameters from their parents (i.e. associated consts of traits)
@@ -3587,7 +3688,6 @@ impl_from!(
Function,
Adt(Struct, Enum, Union),
Trait,
- TraitAlias,
TypeAlias,
Impl,
Const,
@@ -3637,7 +3737,6 @@ impl GenericDef {
GenericDef::Function(it) => it.id.into(),
GenericDef::Adt(it) => it.into(),
GenericDef::Trait(it) => it.id.into(),
- GenericDef::TraitAlias(it) => it.id.into(),
GenericDef::TypeAlias(it) => it.id.into(),
GenericDef::Impl(it) => it.id.into(),
GenericDef::Const(it) => it.id.into(),
@@ -3662,7 +3761,6 @@ impl GenericDef {
GenericDefId::FunctionId(it) => db.function_signature_with_source_map(it).1,
GenericDefId::ImplId(it) => db.impl_signature_with_source_map(it).1,
GenericDefId::StaticId(_) => return,
- GenericDefId::TraitAliasId(it) => db.trait_alias_signature_with_source_map(it).1,
GenericDefId::TraitId(it) => db.trait_signature_with_source_map(it).1,
GenericDefId::TypeAliasId(it) => db.type_alias_signature_with_source_map(it).1,
};
@@ -3672,7 +3770,7 @@ impl GenericDef {
push_ty_diagnostics(
db,
acc,
- db.generic_predicates_without_parent_with_diagnostics(def).1,
+ db.generic_predicates_without_parent_with_diagnostics_ns(def).1,
&source_map,
);
for (param_id, param) in generics.iter_type_or_consts() {
@@ -3699,7 +3797,6 @@ impl GenericDef {
GenericDef::Adt(Adt::Enum(_)) => "enum",
GenericDef::Adt(Adt::Union(_)) => "union",
GenericDef::Trait(_) => "trait",
- GenericDef::TraitAlias(_) => "trait alias",
GenericDef::TypeAlias(_) => "type alias",
GenericDef::Impl(_) => "impl",
GenericDef::Const(_) => "constant",
@@ -3976,49 +4073,25 @@ impl DeriveHelper {
}
}
-// FIXME: Wrong name? This is could also be a registered attribute
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct BuiltinAttr {
- krate: Option<base_db::Crate>,
idx: u32,
}
impl BuiltinAttr {
- // FIXME: consider crates\hir_def\src\nameres\attr_resolution.rs?
- pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self> {
- if let builtin @ Some(_) = Self::builtin(name) {
- return builtin;
- }
- let idx = crate_def_map(db, krate.id)
- .registered_attrs()
- .iter()
- .position(|it| it.as_str() == name)? as u32;
- Some(BuiltinAttr { krate: Some(krate.id), idx })
- }
-
fn builtin(name: &str) -> Option<Self> {
hir_expand::inert_attr_macro::find_builtin_attr_idx(&Symbol::intern(name))
- .map(|idx| BuiltinAttr { krate: None, idx: idx as u32 })
+ .map(|idx| BuiltinAttr { idx: idx as u32 })
}
- pub fn name(&self, db: &dyn HirDatabase) -> Name {
- match self.krate {
- Some(krate) => Name::new_symbol_root(
- crate_def_map(db, krate).registered_attrs()[self.idx as usize].clone(),
- ),
- None => Name::new_symbol_root(Symbol::intern(
- hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].name,
- )),
- }
+ pub fn name(&self) -> Name {
+ Name::new_symbol_root(Symbol::intern(
+ hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].name,
+ ))
}
- pub fn template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate> {
- match self.krate {
- Some(_) => None,
- None => {
- Some(hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].template)
- }
- }
+ pub fn template(&self) -> Option<AttributeTemplate> {
+ Some(hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].template)
}
}
@@ -4154,8 +4227,8 @@ impl TypeParam {
pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
let resolver = self.id.parent().resolver(db);
- let ty =
- TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id.into())).intern(Interner);
+ let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx_no_index(db, self.id.into()))
+ .intern(Interner);
Type::new_with_resolver_inner(db, &resolver, ty)
}
@@ -4163,12 +4236,10 @@ impl TypeParam {
/// parameter, not additional bounds that might be added e.g. by a method if
/// the parameter comes from an impl!
pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
- db.generic_predicates_for_param(self.id.parent(), self.id.into(), None)
+ db.generic_predicates_for_param_ns(self.id.parent(), self.id.into(), None)
.iter()
- .filter_map(|pred| match &pred.skip_binders().skip_binders() {
- hir_ty::WhereClause::Implemented(trait_ref) => {
- Some(Trait::from(trait_ref.hir_trait_id()))
- }
+ .filter_map(|pred| match &pred.kind().skip_binder() {
+ ClauseKind::Trait(trait_ref) => Some(Trait::from(trait_ref.def_id().0)),
_ => None,
})
.collect()
@@ -4424,14 +4495,13 @@ impl Impl {
}
pub fn trait_(self, db: &dyn HirDatabase) -> Option<Trait> {
- let trait_ref = db.impl_trait(self.id)?;
- let id = trait_ref.skip_binders().hir_trait_id();
- Some(Trait { id })
+ let trait_ref = db.impl_trait_ns(self.id)?;
+ let id = trait_ref.skip_binder().def_id;
+ Some(Trait { id: id.0 })
}
pub fn trait_ref(self, db: &dyn HirDatabase) -> Option<TraitRef<'_>> {
- let substs = TyBuilder::placeholder_subst(db, self.id);
- let trait_ref = db.impl_trait(self.id)?.substitute(Interner, &substs);
+ let trait_ref = db.impl_trait_ns(self.id)?.instantiate_identity();
let resolver = self.id.resolver(db);
Some(TraitRef::new_with_resolver(db, &resolver, trait_ref))
}
@@ -4500,7 +4570,7 @@ impl Impl {
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct TraitRef<'db> {
env: Arc<TraitEnvironment>,
- trait_ref: hir_ty::TraitRef,
+ trait_ref: hir_ty::next_solver::TraitRef<'db>,
_pd: PhantomCovariantLifetime<'db>,
}
@@ -4508,7 +4578,7 @@ impl<'db> TraitRef<'db> {
pub(crate) fn new_with_resolver(
db: &'db dyn HirDatabase,
resolver: &Resolver<'_>,
- trait_ref: hir_ty::TraitRef,
+ trait_ref: hir_ty::next_solver::TraitRef<'db>,
) -> Self {
let env = resolver
.generic_def()
@@ -4517,25 +4587,22 @@ impl<'db> TraitRef<'db> {
}
pub fn trait_(&self) -> Trait {
- let id = self.trait_ref.hir_trait_id();
- Trait { id }
+ Trait { id: self.trait_ref.def_id.0 }
}
- pub fn self_ty(&self) -> Type<'_> {
- let ty = self.trait_ref.self_type_parameter(Interner);
- Type { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() }
+ pub fn self_ty(&self) -> TypeNs<'_> {
+ let ty = self.trait_ref.self_ty();
+ TypeNs { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() }
}
/// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the
/// first argument is the `Self` type.
- pub fn get_type_argument(&self, idx: usize) -> Option<Type<'db>> {
- self.trait_ref
- .substitution
- .as_slice(Interner)
- .get(idx)
- .and_then(|arg| arg.ty(Interner))
- .cloned()
- .map(|ty| Type { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() })
+ pub fn get_type_argument(&self, idx: usize) -> Option<TypeNs<'db>> {
+ self.trait_ref.args.as_slice().get(idx).and_then(|arg| arg.ty()).map(|ty| TypeNs {
+ env: self.env.clone(),
+ ty,
+ _pd: PhantomCovariantLifetime::new(),
+ })
}
}
@@ -4591,7 +4658,7 @@ impl Closure {
.iter()
.map(|capture| Type {
env: db.trait_environment_for_body(owner),
- ty: capture.ty(&self.subst),
+ ty: capture.ty(db, &self.subst),
_pd: PhantomCovariantLifetime::new(),
})
.collect()
@@ -4852,42 +4919,80 @@ impl<'db> Type<'db> {
}
pub fn contains_reference(&self, db: &'db dyn HirDatabase) -> bool {
- return go(db, self.env.krate, &self.ty);
+ return go(db, &self.ty);
+
+ fn is_phantom_data(db: &dyn HirDatabase, adt_id: AdtId) -> bool {
+ match adt_id {
+ hir_def::AdtId::StructId(s) => {
+ let flags = db.struct_signature(s).flags;
+ flags.contains(StructFlags::IS_PHANTOM_DATA)
+ }
+ hir_def::AdtId::UnionId(_) => false,
+ hir_def::AdtId::EnumId(_) => false,
+ }
+ }
- fn go(db: &dyn HirDatabase, krate: base_db::Crate, ty: &Ty) -> bool {
+ fn go(db: &dyn HirDatabase, ty: &Ty) -> bool {
match ty.kind(Interner) {
// Reference itself
TyKind::Ref(_, _, _) => true,
// For non-phantom_data adts we check variants/fields as well as generic parameters
- TyKind::Adt(adt_id, substitution)
- if !db.adt_datum(krate, *adt_id).flags.phantom_data =>
- {
- let adt_datum = &db.adt_datum(krate, *adt_id);
- let adt_datum_bound =
- adt_datum.binders.clone().substitute(Interner, substitution);
- adt_datum_bound
- .variants
+ TyKind::Adt(adt_id, substitution) if !is_phantom_data(db, adt_id.0) => {
+ let _variant_id_to_fields = |id: VariantId| {
+ let variant_data = &id.fields(db);
+ if variant_data.fields().is_empty() {
+ vec![]
+ } else {
+ let field_types = db.field_types(id);
+ variant_data
+ .fields()
+ .iter()
+ .map(|(idx, _)| {
+ field_types[idx].clone().substitute(Interner, substitution)
+ })
+ .filter(|it| !it.contains_unknown())
+ .collect()
+ }
+ };
+ let variant_id_to_fields = |_: VariantId| vec![];
+
+ let variants = match adt_id.0 {
+ hir_def::AdtId::StructId(id) => {
+ vec![variant_id_to_fields(id.into())]
+ }
+ hir_def::AdtId::EnumId(id) => id
+ .enum_variants(db)
+ .variants
+ .iter()
+ .map(|&(variant_id, _, _)| variant_id_to_fields(variant_id.into()))
+ .collect(),
+ hir_def::AdtId::UnionId(id) => {
+ vec![variant_id_to_fields(id.into())]
+ }
+ };
+
+ variants
.into_iter()
- .flat_map(|variant| variant.fields.into_iter())
- .any(|ty| go(db, krate, &ty))
+ .flat_map(|variant| variant.into_iter())
+ .any(|ty| go(db, &ty))
|| substitution
.iter(Interner)
.filter_map(|x| x.ty(Interner))
- .any(|ty| go(db, krate, ty))
+ .any(|ty| go(db, ty))
}
// And for `PhantomData<T>`, we check `T`.
TyKind::Adt(_, substitution)
| TyKind::Tuple(_, substitution)
| TyKind::OpaqueType(_, substitution)
| TyKind::AssociatedType(_, substitution)
- | TyKind::FnDef(_, substitution) => substitution
- .iter(Interner)
- .filter_map(|x| x.ty(Interner))
- .any(|ty| go(db, krate, ty)),
+ | TyKind::Alias(AliasTy::Projection(ProjectionTy { substitution, .. }))
+ | TyKind::FnDef(_, substitution) => {
+ substitution.iter(Interner).filter_map(|x| x.ty(Interner)).any(|ty| go(db, ty))
+ }
// For `[T]` or `*T` we check `T`
- TyKind::Array(ty, _) | TyKind::Slice(ty) | TyKind::Raw(_, ty) => go(db, krate, ty),
+ TyKind::Array(ty, _) | TyKind::Slice(ty) | TyKind::Raw(_, ty) => go(db, ty),
// Consider everything else as not reference
_ => false,
@@ -5072,7 +5177,7 @@ impl<'db> Type<'db> {
binders: CanonicalVarKinds::empty(Interner),
};
- db.trait_solve(self.env.krate, self.env.block, goal).is_some()
+ !db.trait_solve(self.env.krate, self.env.block, goal).no_solution()
}
pub fn normalize_trait_assoc_type(
@@ -5520,7 +5625,11 @@ impl<'db> Type<'db> {
.map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d));
_ = method_resolution::iterate_method_candidates_dyn(
- &canonical,
+ &canonical.to_nextsolver(DbInterner::new_with(
+ db,
+ Some(environment.krate),
+ environment.block,
+ )),
db,
environment,
traits_in_scope,
@@ -5607,7 +5716,11 @@ impl<'db> Type<'db> {
.map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d));
_ = method_resolution::iterate_path_candidates(
- &canonical,
+ &canonical.to_nextsolver(DbInterner::new_with(
+ db,
+ Some(environment.krate),
+ environment.block,
+ )),
db,
environment,
traits_in_scope,
@@ -5720,7 +5833,11 @@ impl<'db> Type<'db> {
cb(type_.derived(ty.clone()));
walk_substs(db, type_, substs, cb);
}
- TyKind::AssociatedType(_, substs) => {
+ TyKind::AssociatedType(_, substs)
+ | TyKind::Alias(AliasTy::Projection(hir_ty::ProjectionTy {
+ substitution: substs,
+ ..
+ })) => {
if ty.associated_type_parent_trait(db).is_some() {
cb(type_.derived(ty.clone()));
}
@@ -5803,7 +5920,7 @@ impl<'db> Type<'db> {
pub fn as_type_param(&self, db: &'db dyn HirDatabase) -> Option<TypeParam> {
match self.ty.kind(Interner) {
TyKind::Placeholder(p) => Some(TypeParam {
- id: TypeParamId::from_unchecked(hir_ty::from_placeholder_idx(db, *p)),
+ id: TypeParamId::from_unchecked(hir_ty::from_placeholder_idx(db, *p).0),
}),
_ => None,
}
@@ -5818,7 +5935,8 @@ impl<'db> Type<'db> {
}
pub fn layout(&self, db: &'db dyn HirDatabase) -> Result<Layout, LayoutError> {
- db.layout_of_ty(self.ty.clone(), self.env.clone())
+ let interner = DbInterner::new_with(db, None, None);
+ db.layout_of_ty(self.ty.to_nextsolver(interner), self.env.clone())
.map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap()))
}
@@ -5827,6 +5945,51 @@ impl<'db> Type<'db> {
}
}
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct TypeNs<'db> {
+ env: Arc<TraitEnvironment>,
+ ty: hir_ty::next_solver::Ty<'db>,
+ _pd: PhantomCovariantLifetime<'db>,
+}
+
+impl<'db> TypeNs<'db> {
+ fn new(
+ db: &'db dyn HirDatabase,
+ lexical_env: impl HasResolver,
+ ty: hir_ty::next_solver::Ty<'db>,
+ ) -> Self {
+ let resolver = lexical_env.resolver(db);
+ let environment = resolver
+ .generic_def()
+ .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d));
+ TypeNs { env: environment, ty, _pd: PhantomCovariantLifetime::new() }
+ }
+
+ // FIXME: Find better API that also handles const generics
+ pub fn impls_trait(&self, infcx: InferCtxt<'db>, trait_: Trait, args: &[TypeNs<'db>]) -> bool {
+ let args = GenericArgs::new_from_iter(
+ infcx.interner,
+ [self.ty].into_iter().chain(args.iter().map(|t| t.ty)).map(|t| t.into()),
+ );
+ let trait_ref = hir_ty::next_solver::TraitRef::new(infcx.interner, trait_.id.into(), args);
+
+ let pred_kind = rustc_type_ir::Binder::dummy(rustc_type_ir::PredicateKind::Clause(
+ rustc_type_ir::ClauseKind::Trait(rustc_type_ir::TraitPredicate {
+ trait_ref,
+ polarity: rustc_type_ir::PredicatePolarity::Positive,
+ }),
+ ));
+ let predicate = hir_ty::next_solver::Predicate::new(infcx.interner, pred_kind);
+ let goal = hir_ty::next_solver::Goal::new(
+ infcx.interner,
+ hir_ty::next_solver::ParamEnv::empty(),
+ predicate,
+ );
+ let res = hir_ty::traits::next_trait_solve_in_ctxt(&infcx, goal);
+ res.map_or(false, |res| matches!(res.1, rustc_type_ir::solve::Certainty::Yes))
+ }
+}
+
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
pub struct InlineAsmOperand {
owner: DefWithBodyId,
@@ -6238,12 +6401,6 @@ impl HasCrate for Trait {
}
}
-impl HasCrate for TraitAlias {
- fn krate(&self, db: &dyn HirDatabase) -> Crate {
- self.module(db).krate()
- }
-}
-
impl HasCrate for Static {
fn krate(&self, db: &dyn HirDatabase) -> Crate {
self.module(db).krate()
@@ -6337,12 +6494,6 @@ impl HasContainer for Trait {
}
}
-impl HasContainer for TraitAlias {
- fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
- ItemContainer::Module(Module { id: self.id.lookup(db).container })
- }
-}
-
impl HasContainer for ExternBlock {
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
ItemContainer::Module(Module { id: self.id.lookup(db).container })
@@ -6476,3 +6627,6 @@ pub fn resolve_absolute_path<'a, I: Iterator<Item = Symbol> + Clone + 'a>(
fn as_name_opt(name: Option<impl AsName>) -> Name {
name.map_or_else(Name::missing, |name| name.as_name())
}
+
+pub use hir_ty::next_solver;
+pub use hir_ty::setup_tracing;