Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lower.rs')
| -rw-r--r-- | crates/hir-ty/src/lower.rs | 106 |
1 files changed, 65 insertions, 41 deletions
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 0c68891fe4..65884b28ff 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -27,10 +27,11 @@ use hir_def::{ nameres::MacroSubNs, path::{GenericArg, GenericArgs, ModPath, Path, PathKind, PathSegment, PathSegments}, resolver::{HasResolver, Resolver, TypeNs}, - type_ref::{ConstRefOrPath, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef}, + type_ref::{ConstRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef}, AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, StaticId, - StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId, + StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UnionId, + VariantId, }; use hir_expand::{name::Name, ExpandResult}; use intern::Interned; @@ -43,17 +44,21 @@ use triomphe::Arc; use crate::{ all_super_traits, - consteval::{intern_const_ref, path_to_const, unknown_const, unknown_const_as_generic}, + consteval::{ + intern_const_ref, intern_const_scalar, path_to_const, unknown_const, + unknown_const_as_generic, + }, db::HirDatabase, make_binders, mapping::{from_chalk_trait_id, ToChalk}, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, utils::Generics, utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics}, - AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnPointer, - FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy, - QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, - Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause, + AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy, + FnPointer, FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, + ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, + ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, + TyKind, WhereClause, }; #[derive(Debug)] @@ -106,6 +111,7 @@ pub struct TyLoweringContext<'a> { pub db: &'a dyn HirDatabase, resolver: &'a Resolver, in_binders: DebruijnIndex, + owner: TypeOwnerId, /// Note: Conceptually, it's thinkable that we could be in a location where /// some type params should be represented as placeholders, and others /// should be converted to variables. I think in practice, this isn't @@ -118,13 +124,14 @@ pub struct TyLoweringContext<'a> { } impl<'a> TyLoweringContext<'a> { - pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self { + pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver, owner: TypeOwnerId) -> Self { let impl_trait_mode = ImplTraitLoweringState::Disallowed; let type_param_mode = ParamLoweringMode::Placeholder; let in_binders = DebruijnIndex::INNERMOST; Self { db, resolver, + owner, in_binders, impl_trait_mode, type_param_mode, @@ -235,6 +242,7 @@ impl<'a> TyLoweringContext<'a> { let const_len = const_or_path_to_chalk( self.db, self.resolver, + self.owner, TyBuilder::usize(), len, self.type_param_mode, @@ -840,6 +848,7 @@ impl<'a> TyLoweringContext<'a> { const_or_path_to_chalk( self.db, self.resolver, + self.owner, ty, c, self.type_param_mode, @@ -1356,8 +1365,8 @@ pub(crate) fn field_types_query( }; let generics = generics(db.upcast(), def); let mut res = ArenaMap::default(); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, GenericDefId::from(variant_id.adt_id()).into()) + .with_type_param_mode(ParamLoweringMode::Variable); for (field_id, field_data) in var_data.fields().iter() { res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref))); } @@ -1379,8 +1388,8 @@ pub(crate) fn generic_predicates_for_param_query( assoc_name: Option<Name>, ) -> Arc<[Binders<QuantifiedWhereClause>]> { let resolver = def.resolver(db.upcast()); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, def.into()) + .with_type_param_mode(ParamLoweringMode::Variable); let generics = generics(db.upcast(), def); let mut predicates: Vec<_> = resolver .where_predicates_in_scope() @@ -1468,8 +1477,8 @@ pub(crate) fn trait_environment_query( def: GenericDefId, ) -> Arc<TraitEnvironment> { let resolver = def.resolver(db.upcast()); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Placeholder); + let ctx = TyLoweringContext::new(db, &resolver, def.into()) + .with_type_param_mode(ParamLoweringMode::Placeholder); let mut traits_in_scope = Vec::new(); let mut clauses = Vec::new(); for pred in resolver.where_predicates_in_scope() { @@ -1527,8 +1536,8 @@ pub(crate) fn generic_predicates_query( def: GenericDefId, ) -> Arc<[Binders<QuantifiedWhereClause>]> { let resolver = def.resolver(db.upcast()); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, def.into()) + .with_type_param_mode(ParamLoweringMode::Variable); let generics = generics(db.upcast(), def); let mut predicates = resolver @@ -1582,8 +1591,8 @@ pub(crate) fn generic_defaults_query( def: GenericDefId, ) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> { let resolver = def.resolver(db.upcast()); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, def.into()) + .with_type_param_mode(ParamLoweringMode::Variable); let generic_params = generics(db.upcast(), def); let parent_start_idx = generic_params.len_self(); @@ -1648,11 +1657,11 @@ pub(crate) fn generic_defaults_recover( fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { let data = db.function_data(def); let resolver = def.resolver(db.upcast()); - let ctx_params = TyLoweringContext::new(db, &resolver) + let ctx_params = TyLoweringContext::new(db, &resolver, def.into()) .with_impl_trait_mode(ImplTraitLoweringMode::Variable) .with_type_param_mode(ParamLoweringMode::Variable); let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr)).collect::<Vec<_>>(); - let ctx_ret = TyLoweringContext::new(db, &resolver) + let ctx_ret = TyLoweringContext::new(db, &resolver, def.into()) .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) .with_type_param_mode(ParamLoweringMode::Variable); let ret = ctx_ret.lower_ty(&data.ret_type); @@ -1683,8 +1692,8 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> { let data = db.const_data(def); let generics = generics(db.upcast(), def.into()); let resolver = def.resolver(db.upcast()); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, def.into()) + .with_type_param_mode(ParamLoweringMode::Variable); make_binders(db, &generics, ctx.lower_ty(&data.type_ref)) } @@ -1693,7 +1702,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> { fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> { let data = db.static_data(def); let resolver = def.resolver(db.upcast()); - let ctx = TyLoweringContext::new(db, &resolver); + let ctx = TyLoweringContext::new(db, &resolver, def.into()); Binders::empty(Interner, ctx.lower_ty(&data.type_ref)) } @@ -1702,8 +1711,8 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS let struct_data = db.struct_data(def); let fields = struct_data.variant_data.fields(); let resolver = def.resolver(db.upcast()); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, AdtId::from(def).into()) + .with_type_param_mode(ParamLoweringMode::Variable); let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders(); Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe)) @@ -1715,7 +1724,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T if let StructKind::Unit = struct_data.variant_data.kind() { return type_for_adt(db, def.into()); } - let generics = generics(db.upcast(), def.into()); + let generics = generics(db.upcast(), AdtId::from(def).into()); let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST); make_binders( db, @@ -1729,8 +1738,8 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) let var_data = &enum_data.variants[def.local_id]; let fields = var_data.variant_data.fields(); let resolver = def.parent.resolver(db.upcast()); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, DefWithBodyId::VariantId(def).into()) + .with_type_param_mode(ParamLoweringMode::Variable); let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders(); Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe)) @@ -1762,8 +1771,8 @@ fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { let generics = generics(db.upcast(), t.into()); let resolver = t.resolver(db.upcast()); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, t.into()) + .with_type_param_mode(ParamLoweringMode::Variable); if db.type_alias_data(t).is_extern { Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner)) } else { @@ -1884,8 +1893,8 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde "impl_self_ty_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})" )); let generics = generics(db.upcast(), impl_id.into()); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, impl_id.into()) + .with_type_param_mode(ParamLoweringMode::Variable); make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty)) } @@ -1894,7 +1903,7 @@ pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> T let parent_data = db.generic_params(def.parent()); let data = &parent_data.type_or_consts[def.local_id()]; let resolver = def.parent().resolver(db.upcast()); - let ctx = TyLoweringContext::new(db, &resolver); + let ctx = TyLoweringContext::new(db, &resolver, def.parent().into()); match data { TypeOrConstParamData::TypeParamData(_) => { never!(); @@ -1920,8 +1929,8 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option< let _cx = stdx::panic_context::enter(format!( "impl_trait_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})" )); - let ctx = - TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable); + let ctx = TyLoweringContext::new(db, &resolver, impl_id.into()) + .with_type_param_mode(ParamLoweringMode::Variable); let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders(); let target_trait = impl_data.target_trait.as_ref()?; Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?)) @@ -1934,7 +1943,7 @@ pub(crate) fn return_type_impl_traits( // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe let data = db.function_data(def); let resolver = def.resolver(db.upcast()); - let ctx_ret = TyLoweringContext::new(db, &resolver) + let ctx_ret = TyLoweringContext::new(db, &resolver, def.into()) .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) .with_type_param_mode(ParamLoweringMode::Variable); let _ret = ctx_ret.lower_ty(&data.ret_type); @@ -1969,7 +1978,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>( arg: &'a GenericArg, this: &mut T, for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a, - for_const: impl FnOnce(&mut T, &ConstRefOrPath, Ty) -> Const + 'a, + for_const: impl FnOnce(&mut T, &ConstRef, Ty) -> Const + 'a, ) -> Option<crate::GenericArg> { let kind = match kind_id { Either::Left(_) => ParamKind::Type, @@ -1997,7 +2006,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>( let p = p.mod_path()?; if p.kind == PathKind::Plain { if let [n] = p.segments() { - let c = ConstRefOrPath::Path(n.clone()); + let c = ConstRef::Path(n.clone()); return Some( GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner), ); @@ -2013,15 +2022,16 @@ pub(crate) fn generic_arg_to_chalk<'a, T>( pub(crate) fn const_or_path_to_chalk( db: &dyn HirDatabase, resolver: &Resolver, + owner: TypeOwnerId, expected_ty: Ty, - value: &ConstRefOrPath, + value: &ConstRef, mode: ParamLoweringMode, args: impl FnOnce() -> Generics, debruijn: DebruijnIndex, ) -> Const { match value { - ConstRefOrPath::Scalar(s) => intern_const_ref(db, s, expected_ty, resolver.krate()), - ConstRefOrPath::Path(n) => { + ConstRef::Scalar(s) => intern_const_ref(db, s, expected_ty, resolver.krate()), + ConstRef::Path(n) => { let path = ModPath::from_segments(PathKind::Plain, Some(n.clone())); path_to_const( db, @@ -2034,6 +2044,20 @@ pub(crate) fn const_or_path_to_chalk( ) .unwrap_or_else(|| unknown_const(expected_ty)) } + &ConstRef::Complex(x) => { + let crate_data = &db.crate_graph()[owner.module(db.upcast()).krate()]; + if crate_data.env.get("__ra_is_test_fixture").is_none() && crate_data.origin.is_local() + { + // FIXME: current `InTypeConstId` is very unstable, so we only use it in non local crate + // that are unlikely to be edited. + return unknown_const(expected_ty); + } + let c = db.intern_in_type_const((x, owner)).into(); + intern_const_scalar( + ConstScalar::UnevaluatedConst(c, Substitution::empty(Interner)), + expected_ty, + ) + } } } |