This commit is contained in:
Lukas Wirth 2024-04-06 13:12:07 +02:00
parent 6a852d7627
commit 13890697eb
12 changed files with 121 additions and 136 deletions

View file

@ -285,6 +285,7 @@ pub struct CrateData {
/// For purposes of analysis, crates are anonymous (only names in /// For purposes of analysis, crates are anonymous (only names in
/// `Dependency` matters), this name should only be used for UI. /// `Dependency` matters), this name should only be used for UI.
pub display_name: Option<CrateDisplayName>, pub display_name: Option<CrateDisplayName>,
// FIXME: Arc this
pub cfg_options: CfgOptions, pub cfg_options: CfgOptions,
/// The cfg options that could be used by the crate /// The cfg options that could be used by the crate
pub potential_cfg_options: Option<CfgOptions>, pub potential_cfg_options: Option<CfgOptions>,

View file

@ -737,7 +737,7 @@ impl<'a> AssocItemCollector<'a> {
&AstIdWithPath::new(file_id, ast_id, Clone::clone(path)), &AstIdWithPath::new(file_id, ast_id, Clone::clone(path)),
ctxt, ctxt,
expand_to, expand_to,
self.expander.module.krate(), self.expander.krate(),
resolver, resolver,
) { ) {
Ok(Some(call_id)) => { Ok(Some(call_id)) => {

View file

@ -21,7 +21,6 @@ use crate::{
pub struct Expander { pub struct Expander {
cfg_options: CfgOptions, cfg_options: CfgOptions,
span_map: OnceCell<SpanMap>, span_map: OnceCell<SpanMap>,
krate: CrateId,
current_file_id: HirFileId, current_file_id: HirFileId,
pub(crate) module: ModuleId, pub(crate) module: ModuleId,
/// `recursion_depth == usize::MAX` indicates that the recursion limit has been reached. /// `recursion_depth == usize::MAX` indicates that the recursion limit has been reached.
@ -45,10 +44,13 @@ impl Expander {
recursion_limit, recursion_limit,
cfg_options: db.crate_graph()[module.krate].cfg_options.clone(), cfg_options: db.crate_graph()[module.krate].cfg_options.clone(),
span_map: OnceCell::new(), span_map: OnceCell::new(),
krate: module.krate,
} }
} }
pub fn krate(&self) -> CrateId {
self.module.krate
}
pub fn enter_expand<T: ast::AstNode>( pub fn enter_expand<T: ast::AstNode>(
&mut self, &mut self,
db: &dyn DefDatabase, db: &dyn DefDatabase,
@ -112,7 +114,7 @@ impl Expander {
pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::HasAttrs) -> Attrs { pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::HasAttrs) -> Attrs {
Attrs::filter( Attrs::filter(
db, db,
self.krate, self.krate(),
RawAttrs::new( RawAttrs::new(
db.upcast(), db.upcast(),
owner, owner,

View file

@ -77,30 +77,32 @@ pub(crate) fn path_to_const(
resolver: &Resolver, resolver: &Resolver,
path: &Path, path: &Path,
mode: ParamLoweringMode, mode: ParamLoweringMode,
args_lazy: impl FnOnce() -> Generics, args: impl FnOnce() -> Option<Generics>,
debruijn: DebruijnIndex, debruijn: DebruijnIndex,
expected_ty: Ty, expected_ty: Ty,
) -> Option<Const> { ) -> Option<Const> {
match resolver.resolve_path_in_value_ns_fully(db.upcast(), path) { match resolver.resolve_path_in_value_ns_fully(db.upcast(), path) {
Some(ValueNs::GenericParam(p)) => { Some(ValueNs::GenericParam(p)) => {
let ty = db.const_param_ty(p); let ty = db.const_param_ty(p);
let args = args_lazy();
let value = match mode { let value = match mode {
ParamLoweringMode::Placeholder => { ParamLoweringMode::Placeholder => {
ConstValue::Placeholder(to_placeholder_idx(db, p.into())) ConstValue::Placeholder(to_placeholder_idx(db, p.into()))
} }
ParamLoweringMode::Variable => match args.param_idx(p.into()) { ParamLoweringMode::Variable => {
Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)), let args = args();
None => { match args.as_ref().and_then(|args| args.param_idx(p.into())) {
never!( Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
"Generic list doesn't contain this param: {:?}, {:?}, {:?}", None => {
args, never!(
path, "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
p args,
); path,
return None; p
);
return None;
}
} }
}, }
}; };
Some(ConstData { ty, value }.intern(Interner)) Some(ConstData { ty, value }.intern(Interner))
} }
@ -285,7 +287,6 @@ pub(crate) fn eval_to_const(
expr: ExprId, expr: ExprId,
mode: ParamLoweringMode, mode: ParamLoweringMode,
ctx: &mut InferenceContext<'_>, ctx: &mut InferenceContext<'_>,
args: impl FnOnce() -> Generics,
debruijn: DebruijnIndex, debruijn: DebruijnIndex,
) -> Const { ) -> Const {
let db = ctx.db; let db = ctx.db;
@ -304,7 +305,9 @@ pub(crate) fn eval_to_const(
} }
if let Expr::Path(p) = &ctx.body.exprs[expr] { if let Expr::Path(p) = &ctx.body.exprs[expr] {
let resolver = &ctx.resolver; let resolver = &ctx.resolver;
if let Some(c) = path_to_const(db, resolver, p, mode, args, debruijn, infer[expr].clone()) { if let Some(c) =
path_to_const(db, resolver, p, mode, || ctx.generics(), debruijn, infer[expr].clone())
{
return c; return c;
} }
} }

View file

@ -60,7 +60,7 @@ use crate::{
lower::ImplTraitLoweringMode, lower::ImplTraitLoweringMode,
to_assoc_type_id, to_assoc_type_id,
traits::FnTrait, traits::FnTrait,
utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder}, utils::{Generics, InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId, AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId,
ImplTraitIdx, InEnvironment, Interner, Lifetime, OpaqueTyId, ProjectionTy, Substitution, ImplTraitIdx, InEnvironment, Interner, Lifetime, OpaqueTyId, ProjectionTy, Substitution,
TraitEnvironment, Ty, TyBuilder, TyExt, TraitEnvironment, Ty, TyBuilder, TyExt,
@ -630,6 +630,10 @@ impl<'a> InferenceContext<'a> {
} }
} }
pub(crate) fn generics(&self) -> Option<Generics> {
Some(crate::utils::generics(self.db.upcast(), self.resolver.generic_def()?))
}
// FIXME: This function should be private in module. It is currently only used in the consteval, since we need // FIXME: This function should be private in module. It is currently only used in the consteval, since we need
// `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you // `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you
// used this function for another workaround, mention it here. If you really need this function and believe that // used this function for another workaround, mention it here. If you really need this function and believe that

View file

@ -19,10 +19,6 @@ impl CastCheck {
let expr_ty = table.resolve_ty_shallow(&self.expr_ty); let expr_ty = table.resolve_ty_shallow(&self.expr_ty);
let cast_ty = table.resolve_ty_shallow(&self.cast_ty); let cast_ty = table.resolve_ty_shallow(&self.cast_ty);
if expr_ty.contains_unknown() || cast_ty.contains_unknown() {
return;
}
if table.coerce(&expr_ty, &cast_ty).is_ok() { if table.coerce(&expr_ty, &cast_ty).is_ok() {
return; return;
} }

View file

@ -26,7 +26,7 @@ use crate::{
mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem}, mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem},
to_chalk_trait_id, to_chalk_trait_id,
traits::FnTrait, traits::FnTrait,
utils::{self, elaborate_clause_supertraits, generics, Generics}, utils::{self, elaborate_clause_supertraits, Generics},
Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy, Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy,
DynTyExt, FnAbi, FnPointer, FnSig, Interner, OpaqueTy, ProjectionTyExt, Substitution, Ty, DynTyExt, FnAbi, FnPointer, FnSig, Interner, OpaqueTy, ProjectionTyExt, Substitution, Ty,
TyExt, WhereClause, TyExt, WhereClause,
@ -331,14 +331,10 @@ impl CapturedItemWithoutTy {
place: self.place, place: self.place,
kind: self.kind, kind: self.kind,
span: self.span, span: self.span,
ty: replace_placeholder_with_binder(ctx.db, ctx.owner, ty), ty: replace_placeholder_with_binder(ctx, ty),
}; };
fn replace_placeholder_with_binder( fn replace_placeholder_with_binder(ctx: &mut InferenceContext<'_>, ty: Ty) -> Binders<Ty> {
db: &dyn HirDatabase,
owner: DefWithBodyId,
ty: Ty,
) -> Binders<Ty> {
struct Filler<'a> { struct Filler<'a> {
db: &'a dyn HirDatabase, db: &'a dyn HirDatabase,
generics: Generics, generics: Generics,
@ -379,12 +375,12 @@ impl CapturedItemWithoutTy {
Ok(BoundVar::new(outer_binder, idx).to_ty(Interner)) Ok(BoundVar::new(outer_binder, idx).to_ty(Interner))
} }
} }
let Some(generic_def) = owner.as_generic_def_id() else { let Some(generics) = ctx.generics() else {
return Binders::empty(Interner, ty); return Binders::empty(Interner, ty);
}; };
let filler = &mut Filler { db, generics: generics(db.upcast(), generic_def) }; let filler = &mut Filler { db: ctx.db, generics };
let result = ty.clone().try_fold_with(filler, DebruijnIndex::INNERMOST).unwrap_or(ty); let result = ty.clone().try_fold_with(filler, DebruijnIndex::INNERMOST).unwrap_or(ty);
make_binders(db, &filler.generics, result) make_binders(ctx.db, &filler.generics, result)
} }
} }
} }

View file

@ -1040,18 +1040,12 @@ impl InferenceContext<'_> {
( (
elem_ty, elem_ty,
if let Some(g_def) = self.owner.as_generic_def_id() { consteval::eval_to_const(
let generics = generics(self.db.upcast(), g_def); repeat,
consteval::eval_to_const( ParamLoweringMode::Placeholder,
repeat, self,
ParamLoweringMode::Placeholder, DebruijnIndex::INNERMOST,
self, ),
|| generics,
DebruijnIndex::INNERMOST,
)
} else {
consteval::usize_const(self.db, None, krate)
},
) )
} }
}; };
@ -1852,7 +1846,7 @@ impl InferenceContext<'_> {
ty, ty,
c, c,
ParamLoweringMode::Placeholder, ParamLoweringMode::Placeholder,
|| generics(this.db.upcast(), this.resolver.generic_def().unwrap()), || this.generics(),
DebruijnIndex::INNERMOST, DebruijnIndex::INNERMOST,
) )
}, },

View file

@ -2,13 +2,13 @@
use std::iter::repeat_with; use std::iter::repeat_with;
use chalk_ir::Mutability;
use hir_def::{ use hir_def::{
body::Body, body::Body,
hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId}, hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId},
path::Path, path::Path,
}; };
use hir_expand::name::Name; use hir_expand::name::Name;
use stdx::TupleExt;
use crate::{ use crate::{
consteval::{try_const_usize, usize_const}, consteval::{try_const_usize, usize_const},
@ -16,8 +16,8 @@ use crate::{
infer::{BindingMode, Expectation, InferenceContext, TypeMismatch}, infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
lower::lower_to_chalk_mutability, lower::lower_to_chalk_mutability,
primitive::UintTy, primitive::UintTy,
static_lifetime, InferenceDiagnostic, Interner, Scalar, Substitution, Ty, TyBuilder, TyExt, static_lifetime, InferenceDiagnostic, Interner, Mutability, Scalar, Substitution, Ty,
TyKind, TyBuilder, TyExt, TyKind,
}; };
/// Used to generalize patterns and assignee expressions. /// Used to generalize patterns and assignee expressions.
@ -90,9 +90,6 @@ impl InferenceContext<'_> {
self.unify(&ty, expected); self.unify(&ty, expected);
let substs =
ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
match def { match def {
_ if subs.is_empty() => {} _ if subs.is_empty() => {}
Some(def) => { Some(def) => {
@ -109,8 +106,10 @@ impl InferenceContext<'_> {
let pre_iter = pre.iter().enumerate(); let pre_iter = pre.iter().enumerate();
let post_iter = (post_idx_offset..).zip(post.iter()); let post_iter = (post_idx_offset..).zip(post.iter());
let substs = ty.as_adt().map(TupleExt::tail);
for (i, &subpat) in pre_iter.chain(post_iter) { for (i, &subpat) in pre_iter.chain(post_iter) {
let field_def = { let expected_ty = {
match variant_data.field(&Name::new_tuple_field(i)) { match variant_data.field(&Name::new_tuple_field(i)) {
Some(local_id) => { Some(local_id) => {
if !visibilities[local_id] if !visibilities[local_id]
@ -118,17 +117,17 @@ impl InferenceContext<'_> {
{ {
// FIXME(DIAGNOSE): private tuple field // FIXME(DIAGNOSE): private tuple field
} }
Some(local_id) let f = field_types[local_id].clone();
let expected_ty = match substs {
Some(substs) => f.substitute(Interner, substs),
None => f.substitute(Interner, &Substitution::empty(Interner)),
};
self.normalize_associated_types_in(expected_ty)
} }
None => None, None => self.err_ty(),
} }
}; };
let expected_ty = field_def.map_or(self.err_ty(), |f| {
field_types[f].clone().substitute(Interner, &substs)
});
let expected_ty = self.normalize_associated_types_in(expected_ty);
T::infer(self, subpat, &expected_ty, default_bm); T::infer(self, subpat, &expected_ty, default_bm);
} }
} }
@ -159,9 +158,6 @@ impl InferenceContext<'_> {
self.unify(&ty, expected); self.unify(&ty, expected);
let substs =
ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
match def { match def {
_ if subs.len() == 0 => {} _ if subs.len() == 0 => {}
Some(def) => { Some(def) => {
@ -169,8 +165,10 @@ impl InferenceContext<'_> {
let variant_data = def.variant_data(self.db.upcast()); let variant_data = def.variant_data(self.db.upcast());
let visibilities = self.db.field_visibilities(def); let visibilities = self.db.field_visibilities(def);
let substs = ty.as_adt().map(TupleExt::tail);
for (name, inner) in subs { for (name, inner) in subs {
let field_def = { let expected_ty = {
match variant_data.field(&name) { match variant_data.field(&name) {
Some(local_id) => { Some(local_id) => {
if !visibilities[local_id] if !visibilities[local_id]
@ -181,23 +179,23 @@ impl InferenceContext<'_> {
private: true, private: true,
}); });
} }
Some(local_id) let f = field_types[local_id].clone();
let expected_ty = match substs {
Some(substs) => f.substitute(Interner, substs),
None => f.substitute(Interner, &Substitution::empty(Interner)),
};
self.normalize_associated_types_in(expected_ty)
} }
None => { None => {
self.push_diagnostic(InferenceDiagnostic::NoSuchField { self.push_diagnostic(InferenceDiagnostic::NoSuchField {
field: inner.into(), field: inner.into(),
private: false, private: false,
}); });
None self.err_ty()
} }
} }
}; };
let expected_ty = field_def.map_or(self.err_ty(), |f| {
field_types[f].clone().substitute(Interner, &substs)
});
let expected_ty = self.normalize_associated_types_in(expected_ty);
T::infer(self, inner, &expected_ty, default_bm); T::infer(self, inner, &expected_ty, default_bm);
} }
} }

View file

@ -62,8 +62,8 @@ use crate::{
mapping::{from_chalk_trait_id, lt_to_placeholder_idx, ToChalk}, mapping::{from_chalk_trait_id, lt_to_placeholder_idx, ToChalk},
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
utils::{ utils::{
all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics, self, all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
InTypeConstIdMetadata, Generics, InTypeConstIdMetadata,
}, },
AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy, AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
FnAbi, FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime, FnAbi, FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime,
@ -245,13 +245,8 @@ impl<'a> TyLoweringContext<'a> {
) )
} }
fn generics(&self) -> Generics { fn generics(&self) -> Option<Generics> {
generics( Some(generics(self.db.upcast(), self.resolver.generic_def()?))
self.db.upcast(),
self.resolver
.generic_def()
.expect("there should be generics if there's a generic param"),
)
} }
pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) { pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
@ -352,8 +347,7 @@ impl<'a> TyLoweringContext<'a> {
let idx = counter.get(); let idx = counter.get();
// FIXME we're probably doing something wrong here // FIXME we're probably doing something wrong here
counter.set(idx + count_impl_traits(type_ref) as u16); counter.set(idx + count_impl_traits(type_ref) as u16);
if let Some(def) = self.resolver.generic_def() { if let Some(generics) = self.generics() {
let generics = generics(self.db.upcast(), def);
let param = generics let param = generics
.iter() .iter()
.filter(|(_, data)| { .filter(|(_, data)| {
@ -388,8 +382,7 @@ impl<'a> TyLoweringContext<'a> {
const_params, const_params,
_impl_trait_params, _impl_trait_params,
_lifetime_params, _lifetime_params,
) = if let Some(def) = self.resolver.generic_def() { ) = if let Some(generics) = self.generics() {
let generics = generics(self.db.upcast(), def);
generics.provenance_split() generics.provenance_split()
} else { } else {
(0, 0, 0, 0, 0, 0) (0, 0, 0, 0, 0, 0)
@ -577,44 +570,40 @@ impl<'a> TyLoweringContext<'a> {
// FIXME(trait_alias): Implement trait alias. // FIXME(trait_alias): Implement trait alias.
return (TyKind::Error.intern(Interner), None); return (TyKind::Error.intern(Interner), None);
} }
TypeNs::GenericParam(param_id) => { TypeNs::GenericParam(param_id) => match self.type_param_mode {
let generics = generics( ParamLoweringMode::Placeholder => {
self.db.upcast(), TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
self.resolver.generic_def().expect("generics in scope"), }
); ParamLoweringMode::Variable => {
match self.type_param_mode { let idx = match self
ParamLoweringMode::Placeholder => { .generics()
TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into())) .expect("generics in scope")
} .param_idx(param_id.into())
ParamLoweringMode::Variable => { {
let idx = match generics.param_idx(param_id.into()) { None => {
None => { never!("no matching generics");
never!("no matching generics"); return (TyKind::Error.intern(Interner), None);
return (TyKind::Error.intern(Interner), None); }
} Some(idx) => idx,
Some(idx) => idx, };
};
TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
}
} }
.intern(Interner)
} }
.intern(Interner),
TypeNs::SelfType(impl_id) => { TypeNs::SelfType(impl_id) => {
let def = let generics = self.generics().expect("impl should have generic param scope");
self.resolver.generic_def().expect("impl should have generic param scope");
let generics = generics(self.db.upcast(), def);
match self.type_param_mode { match self.type_param_mode {
ParamLoweringMode::Placeholder => { ParamLoweringMode::Placeholder => {
// `def` can be either impl itself or item within, and we need impl itself // `def` can be either impl itself or item within, and we need impl itself
// now. // now.
let generics = generics.parent_generics().unwrap_or(&generics); let generics = generics.parent_or_self();
let subst = generics.placeholder_subst(self.db); let subst = generics.placeholder_subst(self.db);
self.db.impl_self_ty(impl_id).substitute(Interner, &subst) self.db.impl_self_ty(impl_id).substitute(Interner, &subst)
} }
ParamLoweringMode::Variable => { ParamLoweringMode::Variable => {
let starting_from = match def { let starting_from = match generics.def() {
GenericDefId::ImplId(_) => 0, GenericDefId::ImplId(_) => 0,
// `def` is an item within impl. We need to substitute `BoundVar`s but // `def` is an item within impl. We need to substitute `BoundVar`s but
// remember that they are for parent (i.e. impl) generic params so they // remember that they are for parent (i.e. impl) generic params so they
@ -682,12 +671,12 @@ impl<'a> TyLoweringContext<'a> {
} }
fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty { fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
let Some((def, res)) = self.resolver.generic_def().zip(res) else { let Some((generics, res)) = self.generics().zip(res) else {
return TyKind::Error.intern(Interner); return TyKind::Error.intern(Interner);
}; };
let ty = named_associated_type_shorthand_candidates( let ty = named_associated_type_shorthand_candidates(
self.db, self.db,
def, generics.def(),
res, res,
Some(segment.name.clone()), Some(segment.name.clone()),
move |name, t, associated_ty| { move |name, t, associated_ty| {
@ -699,7 +688,6 @@ impl<'a> TyLoweringContext<'a> {
let parent_subst = match self.type_param_mode { let parent_subst = match self.type_param_mode {
ParamLoweringMode::Placeholder => { ParamLoweringMode::Placeholder => {
// if we're lowering to placeholders, we have to put them in now. // if we're lowering to placeholders, we have to put them in now.
let generics = generics(self.db.upcast(), def);
let s = generics.placeholder_subst(self.db); let s = generics.placeholder_subst(self.db);
s.apply(parent_subst, Interner) s.apply(parent_subst, Interner)
} }
@ -721,7 +709,7 @@ impl<'a> TyLoweringContext<'a> {
None, None,
); );
let len_self = generics(self.db.upcast(), associated_ty.into()).len_self(); let len_self = utils::generics(self.db.upcast(), associated_ty.into()).len_self();
let substs = Substitution::from_iter( let substs = Substitution::from_iter(
Interner, Interner,
@ -1029,18 +1017,17 @@ impl<'a> TyLoweringContext<'a> {
| WherePredicate::TypeBound { target, bound } => { | WherePredicate::TypeBound { target, bound } => {
let self_ty = match target { let self_ty = match target {
WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref), WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
WherePredicateTypeTarget::TypeOrConstParam(param_id) => { &WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
let generic_def = self.resolver.generic_def().expect("generics in scope"); let def = self.resolver.generic_def().expect("generics in scope");
let generics = generics(self.db.upcast(), generic_def); let param_id = hir_def::TypeOrConstParamId { parent: def, local_id };
let param_id = hir_def::TypeOrConstParamId {
parent: generic_def,
local_id: *param_id,
};
let placeholder = to_placeholder_idx(self.db, param_id);
match self.type_param_mode { match self.type_param_mode {
ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder), ParamLoweringMode::Placeholder => {
TyKind::Placeholder(to_placeholder_idx(self.db, param_id))
}
ParamLoweringMode::Variable => { ParamLoweringMode::Variable => {
let idx = generics.param_idx(param_id).expect("matching generics"); let idx = generics(self.db.upcast(), def)
.param_idx(param_id)
.expect("matching generics");
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx)) TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
} }
} }
@ -1218,8 +1205,8 @@ impl<'a> TyLoweringContext<'a> {
}); });
if let Some(target_param_idx) = target_param_idx { if let Some(target_param_idx) = target_param_idx {
let mut counter = 0; let mut counter = 0;
for (idx, data) in self.generics().params.type_or_consts.iter() let generics = self.generics().expect("generics in scope");
{ for (idx, data) in generics.params.type_or_consts.iter() {
// Count the number of `impl Trait` things that appear before // Count the number of `impl Trait` things that appear before
// the target of our `bound`. // the target of our `bound`.
// Our counter within `impl_trait_mode` should be that number // Our counter within `impl_trait_mode` should be that number
@ -1409,10 +1396,7 @@ impl<'a> TyLoweringContext<'a> {
LifetimeData::Placeholder(lt_to_placeholder_idx(self.db, id)) LifetimeData::Placeholder(lt_to_placeholder_idx(self.db, id))
} }
ParamLoweringMode::Variable => { ParamLoweringMode::Variable => {
let generics = generics( let generics = self.generics().expect("generics in scope");
self.db.upcast(),
self.resolver.generic_def().expect("generics in scope"),
);
let idx = match generics.lifetime_idx(id) { let idx = match generics.lifetime_idx(id) {
None => return error_lifetime(), None => return error_lifetime(),
Some(idx) => idx, Some(idx) => idx,
@ -2258,7 +2242,7 @@ pub(crate) fn const_or_path_to_chalk(
expected_ty: Ty, expected_ty: Ty,
value: &ConstRef, value: &ConstRef,
mode: ParamLoweringMode, mode: ParamLoweringMode,
args: impl FnOnce() -> Generics, args: impl FnOnce() -> Option<Generics>,
debruijn: DebruijnIndex, debruijn: DebruijnIndex,
) -> Const { ) -> Const {
match value { match value {
@ -2277,7 +2261,7 @@ pub(crate) fn const_or_path_to_chalk(
.unwrap_or_else(|| unknown_const(expected_ty)) .unwrap_or_else(|| unknown_const(expected_ty))
} }
&ConstRef::Complex(it) => { &ConstRef::Complex(it) => {
let crate_data = &db.crate_graph()[owner.module(db.upcast()).krate()]; let crate_data = &db.crate_graph()[resolver.krate()];
if crate_data.env.get("__ra_is_test_fixture").is_none() && crate_data.origin.is_local() 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 // FIXME: current `InTypeConstId` is very unstable, so we only use it in non local crate

View file

@ -262,7 +262,7 @@ impl<'a> ClosureSubst<'a> {
} }
} }
#[derive(Debug)] #[derive(Clone, Debug)]
pub(crate) struct Generics { pub(crate) struct Generics {
def: GenericDefId, def: GenericDefId,
pub(crate) params: Interned<GenericParams>, pub(crate) params: Interned<GenericParams>,
@ -274,6 +274,10 @@ impl Generics {
self.iter().map(|(id, _)| id) self.iter().map(|(id, _)| id)
} }
pub(crate) fn def(&self) -> GenericDefId {
self.def
}
/// Iterator over types and const params of self, then parent. /// Iterator over types and const params of self, then parent.
pub(crate) fn iter<'a>( pub(crate) fn iter<'a>(
&'a self, &'a self,
@ -450,6 +454,10 @@ impl Generics {
self.parent_generics.as_deref() self.parent_generics.as_deref()
} }
pub(crate) fn parent_or_self(&self) -> &Generics {
self.parent_generics.as_deref().unwrap_or(self)
}
/// Returns a Substitution that replaces each parameter by a bound variable. /// Returns a Substitution that replaces each parameter by a bound variable.
pub(crate) fn bound_vars_subst( pub(crate) fn bound_vars_subst(
&self, &self,

View file

@ -10,7 +10,6 @@ rust-version.workspace = true
[features] [features]
tracking = [] tracking = []
default = ["tracking"]
[lints] [lints]
workspace = true workspace = true