mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 14:03:35 +00:00
Auto merge of #17023 - Veykril:cleanup, r=Veykril
internal: Some cleanup and perf
This commit is contained in:
commit
d9c29afaee
23 changed files with 244 additions and 228 deletions
|
@ -285,9 +285,9 @@ 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>,
|
||||||
pub cfg_options: CfgOptions,
|
pub cfg_options: Arc<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<Arc<CfgOptions>>,
|
||||||
pub env: Env,
|
pub env: Env,
|
||||||
pub dependencies: Vec<Dependency>,
|
pub dependencies: Vec<Dependency>,
|
||||||
pub origin: CrateOrigin,
|
pub origin: CrateOrigin,
|
||||||
|
@ -328,8 +328,8 @@ impl CrateGraph {
|
||||||
edition: Edition,
|
edition: Edition,
|
||||||
display_name: Option<CrateDisplayName>,
|
display_name: Option<CrateDisplayName>,
|
||||||
version: Option<String>,
|
version: Option<String>,
|
||||||
cfg_options: CfgOptions,
|
cfg_options: Arc<CfgOptions>,
|
||||||
potential_cfg_options: Option<CfgOptions>,
|
potential_cfg_options: Option<Arc<CfgOptions>>,
|
||||||
env: Env,
|
env: Env,
|
||||||
is_proc_macro: bool,
|
is_proc_macro: bool,
|
||||||
origin: CrateOrigin,
|
origin: CrateOrigin,
|
||||||
|
|
|
@ -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)) => {
|
||||||
|
|
|
@ -191,8 +191,6 @@ impl StructData {
|
||||||
let krate = loc.container.krate;
|
let krate = loc.container.krate;
|
||||||
let item_tree = loc.id.item_tree(db);
|
let item_tree = loc.id.item_tree(db);
|
||||||
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
|
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
|
||||||
let cfg_options = db.crate_graph()[krate].cfg_options.clone();
|
|
||||||
|
|
||||||
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
|
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
|
||||||
|
|
||||||
let mut flags = StructFlags::NO_FLAGS;
|
let mut flags = StructFlags::NO_FLAGS;
|
||||||
|
@ -219,7 +217,7 @@ impl StructData {
|
||||||
loc.id.file_id(),
|
loc.id.file_id(),
|
||||||
loc.container.local_id,
|
loc.container.local_id,
|
||||||
&item_tree,
|
&item_tree,
|
||||||
&cfg_options,
|
&db.crate_graph()[krate].cfg_options,
|
||||||
&strukt.fields,
|
&strukt.fields,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
@ -248,8 +246,6 @@ impl StructData {
|
||||||
let krate = loc.container.krate;
|
let krate = loc.container.krate;
|
||||||
let item_tree = loc.id.item_tree(db);
|
let item_tree = loc.id.item_tree(db);
|
||||||
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
|
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
|
||||||
let cfg_options = db.crate_graph()[krate].cfg_options.clone();
|
|
||||||
|
|
||||||
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
|
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
|
||||||
let mut flags = StructFlags::NO_FLAGS;
|
let mut flags = StructFlags::NO_FLAGS;
|
||||||
if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() {
|
if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() {
|
||||||
|
@ -266,7 +262,7 @@ impl StructData {
|
||||||
loc.id.file_id(),
|
loc.id.file_id(),
|
||||||
loc.container.local_id,
|
loc.container.local_id,
|
||||||
&item_tree,
|
&item_tree,
|
||||||
&cfg_options,
|
&db.crate_graph()[krate].cfg_options,
|
||||||
&union.fields,
|
&union.fields,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
@ -338,7 +334,6 @@ impl EnumVariantData {
|
||||||
let container = loc.parent.lookup(db).container;
|
let container = loc.parent.lookup(db).container;
|
||||||
let krate = container.krate;
|
let krate = container.krate;
|
||||||
let item_tree = loc.id.item_tree(db);
|
let item_tree = loc.id.item_tree(db);
|
||||||
let cfg_options = db.crate_graph()[krate].cfg_options.clone();
|
|
||||||
let variant = &item_tree[loc.id.value];
|
let variant = &item_tree[loc.id.value];
|
||||||
|
|
||||||
let (var_data, diagnostics) = lower_fields(
|
let (var_data, diagnostics) = lower_fields(
|
||||||
|
@ -347,7 +342,7 @@ impl EnumVariantData {
|
||||||
loc.id.file_id(),
|
loc.id.file_id(),
|
||||||
container.local_id,
|
container.local_id,
|
||||||
&item_tree,
|
&item_tree,
|
||||||
&cfg_options,
|
&db.crate_graph()[krate].cfg_options,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
Some(item_tree[loc.parent.lookup(db).id.value].visibility),
|
Some(item_tree[loc.parent.lookup(db).id.value].visibility),
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,6 +11,7 @@ use hir_expand::{
|
||||||
};
|
};
|
||||||
use limit::Limit;
|
use limit::Limit;
|
||||||
use syntax::{ast, Parse};
|
use syntax::{ast, Parse};
|
||||||
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attr::Attrs, db::DefDatabase, lower::LowerCtx, path::Path, AsMacroCall, MacroId, ModuleId,
|
attr::Attrs, db::DefDatabase, lower::LowerCtx, path::Path, AsMacroCall, MacroId, ModuleId,
|
||||||
|
@ -19,9 +20,8 @@ use crate::{
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Expander {
|
pub struct Expander {
|
||||||
cfg_options: CfgOptions,
|
cfg_options: Arc<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 +45,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 +115,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,
|
||||||
|
|
|
@ -3,13 +3,15 @@
|
||||||
//! generic parameters. See also the `Generics` type and the `generics_of` query
|
//! generic parameters. See also the `Generics` type and the `generics_of` query
|
||||||
//! in rustc.
|
//! in rustc.
|
||||||
|
|
||||||
|
use std::ops;
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
name::{AsName, Name},
|
name::{AsName, Name},
|
||||||
ExpandResult,
|
ExpandResult,
|
||||||
};
|
};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use la_arena::{Arena, Idx};
|
use la_arena::Arena;
|
||||||
use once_cell::unsync::Lazy;
|
use once_cell::unsync::Lazy;
|
||||||
use stdx::impl_from;
|
use stdx::impl_from;
|
||||||
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
|
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
|
||||||
|
@ -23,7 +25,7 @@ use crate::{
|
||||||
nameres::{DefMap, MacroSubNs},
|
nameres::{DefMap, MacroSubNs},
|
||||||
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
|
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
|
||||||
AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LifetimeParamId,
|
AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LifetimeParamId,
|
||||||
LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
|
LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Data about a generic type parameter (to a function, struct, impl, ...).
|
/// Data about a generic type parameter (to a function, struct, impl, ...).
|
||||||
|
@ -158,6 +160,20 @@ pub struct GenericParams {
|
||||||
pub where_predicates: Box<[WherePredicate]>,
|
pub where_predicates: Box<[WherePredicate]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ops::Index<LocalTypeOrConstParamId> for GenericParams {
|
||||||
|
type Output = TypeOrConstParamData;
|
||||||
|
fn index(&self, index: LocalTypeOrConstParamId) -> &TypeOrConstParamData {
|
||||||
|
&self.type_or_consts[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Index<LocalLifetimeParamId> for GenericParams {
|
||||||
|
type Output = LifetimeParamData;
|
||||||
|
fn index(&self, index: LocalLifetimeParamId) -> &LifetimeParamData {
|
||||||
|
&self.lifetimes[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
|
/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
|
||||||
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
|
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
|
||||||
/// It might still result in multiple actual predicates though, because of
|
/// It might still result in multiple actual predicates though, because of
|
||||||
|
@ -199,7 +215,7 @@ impl GenericParamsCollector {
|
||||||
lower_ctx: &LowerCtx<'_>,
|
lower_ctx: &LowerCtx<'_>,
|
||||||
node: &dyn HasGenericParams,
|
node: &dyn HasGenericParams,
|
||||||
add_param_attrs: impl FnMut(
|
add_param_attrs: impl FnMut(
|
||||||
Either<Idx<TypeOrConstParamData>, Idx<LifetimeParamData>>,
|
Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
|
||||||
ast::GenericParam,
|
ast::GenericParam,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
|
@ -227,7 +243,7 @@ impl GenericParamsCollector {
|
||||||
lower_ctx: &LowerCtx<'_>,
|
lower_ctx: &LowerCtx<'_>,
|
||||||
params: ast::GenericParamList,
|
params: ast::GenericParamList,
|
||||||
mut add_param_attrs: impl FnMut(
|
mut add_param_attrs: impl FnMut(
|
||||||
Either<Idx<TypeOrConstParamData>, Idx<LifetimeParamData>>,
|
Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
|
||||||
ast::GenericParam,
|
ast::GenericParam,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
|
@ -416,16 +432,16 @@ impl GenericParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator of type_or_consts field
|
/// Iterator of type_or_consts field
|
||||||
pub fn iter(
|
pub fn iter_type_or_consts(
|
||||||
&self,
|
&self,
|
||||||
) -> impl DoubleEndedIterator<Item = (Idx<TypeOrConstParamData>, &TypeOrConstParamData)> {
|
) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> {
|
||||||
self.type_or_consts.iter()
|
self.type_or_consts.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator of lifetimes field
|
/// Iterator of lifetimes field
|
||||||
pub fn iter_lt(
|
pub fn iter_lt(
|
||||||
&self,
|
&self,
|
||||||
) -> impl DoubleEndedIterator<Item = (Idx<LifetimeParamData>, &LifetimeParamData)> {
|
) -> impl DoubleEndedIterator<Item = (LocalLifetimeParamId, &LifetimeParamData)> {
|
||||||
self.lifetimes.iter()
|
self.lifetimes.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.type_or_const_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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -453,7 +453,7 @@ impl HirDisplay for Const {
|
||||||
ConstValue::Placeholder(idx) => {
|
ConstValue::Placeholder(idx) => {
|
||||||
let id = from_placeholder_idx(f.db, *idx);
|
let id = from_placeholder_idx(f.db, *idx);
|
||||||
let generics = generics(f.db.upcast(), id.parent);
|
let generics = generics(f.db.upcast(), id.parent);
|
||||||
let param_data = &generics.params.type_or_consts[id.local_id];
|
let param_data = &generics.params[id.local_id];
|
||||||
write!(f, "{}", param_data.name().unwrap().display(f.db.upcast()))?;
|
write!(f, "{}", param_data.name().unwrap().display(f.db.upcast()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1176,7 +1176,7 @@ impl HirDisplay for Ty {
|
||||||
TyKind::Placeholder(idx) => {
|
TyKind::Placeholder(idx) => {
|
||||||
let id = from_placeholder_idx(db, *idx);
|
let id = from_placeholder_idx(db, *idx);
|
||||||
let generics = generics(db.upcast(), id.parent);
|
let generics = generics(db.upcast(), id.parent);
|
||||||
let param_data = &generics.params.type_or_consts[id.local_id];
|
let param_data = &generics.params[id.local_id];
|
||||||
match param_data {
|
match param_data {
|
||||||
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
|
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
|
||||||
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
|
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
|
||||||
|
@ -1724,7 +1724,7 @@ impl HirDisplay for LifetimeData {
|
||||||
LifetimeData::Placeholder(idx) => {
|
LifetimeData::Placeholder(idx) => {
|
||||||
let id = lt_from_placeholder_idx(f.db, *idx);
|
let id = lt_from_placeholder_idx(f.db, *idx);
|
||||||
let generics = generics(f.db.upcast(), id.parent);
|
let generics = generics(f.db.upcast(), id.parent);
|
||||||
let param_data = &generics.params.lifetimes[id.local_id];
|
let param_data = &generics.params[id.local_id];
|
||||||
write!(f, "{}", param_data.name.display(f.db.upcast()))?;
|
write!(f, "{}", param_data.name.display(f.db.upcast()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -361,7 +357,7 @@ impl CapturedItemWithoutTy {
|
||||||
outer_binder: DebruijnIndex,
|
outer_binder: DebruijnIndex,
|
||||||
) -> Result<chalk_ir::Const<Interner>, Self::Error> {
|
) -> Result<chalk_ir::Const<Interner>, Self::Error> {
|
||||||
let x = from_placeholder_idx(self.db, idx);
|
let x = from_placeholder_idx(self.db, idx);
|
||||||
let Some(idx) = self.generics.param_idx(x) else {
|
let Some(idx) = self.generics.type_or_const_param_idx(x) else {
|
||||||
return Err(());
|
return Err(());
|
||||||
};
|
};
|
||||||
Ok(BoundVar::new(outer_binder, idx).to_const(Interner, ty))
|
Ok(BoundVar::new(outer_binder, idx).to_const(Interner, ty))
|
||||||
|
@ -373,18 +369,18 @@ impl CapturedItemWithoutTy {
|
||||||
outer_binder: DebruijnIndex,
|
outer_binder: DebruijnIndex,
|
||||||
) -> std::result::Result<Ty, Self::Error> {
|
) -> std::result::Result<Ty, Self::Error> {
|
||||||
let x = from_placeholder_idx(self.db, idx);
|
let x = from_placeholder_idx(self.db, idx);
|
||||||
let Some(idx) = self.generics.param_idx(x) else {
|
let Some(idx) = self.generics.type_or_const_param_idx(x) else {
|
||||||
return Err(());
|
return Err(());
|
||||||
};
|
};
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,7 +288,7 @@ impl Hash for ConstScalar {
|
||||||
|
|
||||||
/// Return an index of a parameter in the generic type parameter list by it's id.
|
/// Return an index of a parameter in the generic type parameter list by it's id.
|
||||||
pub fn param_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<usize> {
|
pub fn param_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<usize> {
|
||||||
generics(db.upcast(), id.parent).param_idx(id)
|
generics(db.upcast(), id.parent).type_or_const_param_idx(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T>
|
pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T>
|
||||||
|
@ -603,15 +603,17 @@ pub enum ImplTraitId {
|
||||||
}
|
}
|
||||||
impl_intern_value_trivial!(ImplTraitId);
|
impl_intern_value_trivial!(ImplTraitId);
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(PartialEq, Eq, Debug, Hash)]
|
||||||
pub struct ImplTraits {
|
pub struct ImplTraits {
|
||||||
pub(crate) impl_traits: Arena<ImplTrait>,
|
pub(crate) impl_traits: Arena<ImplTrait>,
|
||||||
}
|
}
|
||||||
|
|
||||||
has_interner!(ImplTraits);
|
has_interner!(ImplTraits);
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(PartialEq, Eq, Debug, Hash)]
|
||||||
pub struct ImplTrait {
|
pub struct ImplTrait {
|
||||||
|
// FIXME: Should be Arc<[QuantifiedWhereClause]>, but the HasInterner impl for Arc is missing a
|
||||||
|
// ?Sized bound
|
||||||
pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
|
pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>) {
|
||||||
|
@ -321,7 +316,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
// place even if we encounter more opaque types while
|
// place even if we encounter more opaque types while
|
||||||
// lowering the bounds
|
// lowering the bounds
|
||||||
let idx = opaque_type_data.borrow_mut().alloc(ImplTrait {
|
let idx = opaque_type_data.borrow_mut().alloc(ImplTrait {
|
||||||
bounds: crate::make_single_type_binders(Vec::new()),
|
bounds: crate::make_single_type_binders(Vec::default()),
|
||||||
});
|
});
|
||||||
// We don't want to lower the bounds inside the binders
|
// We don't want to lower the bounds inside the binders
|
||||||
// we're currently in, because they don't end up inside
|
// we're currently in, because they don't end up inside
|
||||||
|
@ -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")
|
||||||
}
|
.type_or_const_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,
|
||||||
|
@ -1019,46 +1007,43 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
|
self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn lower_where_predicate(
|
pub(crate) fn lower_where_predicate<'b>(
|
||||||
&self,
|
&'b self,
|
||||||
where_predicate: &WherePredicate,
|
where_predicate: &'b WherePredicate,
|
||||||
ignore_bindings: bool,
|
ignore_bindings: bool,
|
||||||
) -> impl Iterator<Item = QuantifiedWhereClause> {
|
) -> impl Iterator<Item = QuantifiedWhereClause> + 'b {
|
||||||
match where_predicate {
|
match where_predicate {
|
||||||
WherePredicate::ForLifetime { target, bound, .. }
|
WherePredicate::ForLifetime { target, bound, .. }
|
||||||
| 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)
|
||||||
|
.type_or_const_param_idx(param_id)
|
||||||
|
.expect("matching generics");
|
||||||
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
|
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.intern(Interner)
|
.intern(Interner)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.lower_type_bound(bound, self_ty, ignore_bindings)
|
Either::Left(self.lower_type_bound(bound, self_ty, ignore_bindings))
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.into_iter()
|
|
||||||
}
|
}
|
||||||
WherePredicate::Lifetime { bound, target } => {
|
WherePredicate::Lifetime { bound, target } => Either::Right(iter::once(
|
||||||
vec![crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives {
|
crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives {
|
||||||
a: self.lower_lifetime(bound),
|
a: self.lower_lifetime(bound),
|
||||||
b: self.lower_lifetime(target),
|
b: self.lower_lifetime(target),
|
||||||
}))]
|
})),
|
||||||
.into_iter()
|
)),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn lower_type_bound(
|
pub(crate) fn lower_type_bound(
|
||||||
|
@ -1218,8 +1203,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
|
||||||
|
@ -1393,8 +1378,8 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
crate::wrap_empty_binders(clause)
|
crate::wrap_empty_binders(clause)
|
||||||
});
|
});
|
||||||
predicates.extend(sized_clause);
|
predicates.extend(sized_clause);
|
||||||
predicates.shrink_to_fit();
|
|
||||||
}
|
}
|
||||||
|
predicates.shrink_to_fit();
|
||||||
predicates
|
predicates
|
||||||
});
|
});
|
||||||
ImplTrait { bounds: crate::make_single_type_binders(predicates) }
|
ImplTrait { bounds: crate::make_single_type_binders(predicates) }
|
||||||
|
@ -1409,10 +1394,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,
|
||||||
|
@ -1523,7 +1505,7 @@ fn named_associated_type_shorthand_candidates<R>(
|
||||||
// Handle `Self::Type` referring to own associated type in trait definitions
|
// Handle `Self::Type` referring to own associated type in trait definitions
|
||||||
if let GenericDefId::TraitId(trait_id) = param_id.parent() {
|
if let GenericDefId::TraitId(trait_id) = param_id.parent() {
|
||||||
let trait_generics = generics(db.upcast(), trait_id.into());
|
let trait_generics = generics(db.upcast(), trait_id.into());
|
||||||
if trait_generics.params.type_or_consts[param_id.local_id()].is_trait_self() {
|
if trait_generics.params[param_id.local_id()].is_trait_self() {
|
||||||
let def_generics = generics(db.upcast(), def);
|
let def_generics = generics(db.upcast(), def);
|
||||||
let starting_idx = match def {
|
let starting_idx = match def {
|
||||||
GenericDefId::TraitId(_) => 0,
|
GenericDefId::TraitId(_) => 0,
|
||||||
|
@ -2258,7 +2240,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 +2259,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
|
||||||
|
|
|
@ -495,9 +495,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
||||||
ty,
|
ty,
|
||||||
value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
|
value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
|
||||||
DebruijnIndex::INNERMOST,
|
DebruijnIndex::INNERMOST,
|
||||||
gen.param_idx(p.into()).ok_or(MirLowerError::TypeError(
|
gen.type_or_const_param_idx(p.into()).ok_or(
|
||||||
"fail to lower const generic param",
|
MirLowerError::TypeError(
|
||||||
))?,
|
"fail to lower const generic param",
|
||||||
|
),
|
||||||
|
)?,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
.intern(Interner),
|
.intern(Interner),
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl FallibleTypeFolder<Interner> for Filler<'_> {
|
||||||
_outer_binder: DebruijnIndex,
|
_outer_binder: DebruijnIndex,
|
||||||
) -> std::result::Result<chalk_ir::Const<Interner>, Self::Error> {
|
) -> std::result::Result<chalk_ir::Const<Interner>, Self::Error> {
|
||||||
let it = from_placeholder_idx(self.db, idx);
|
let it = from_placeholder_idx(self.db, idx);
|
||||||
let Some(idx) = self.generics.as_ref().and_then(|g| g.param_idx(it)) else {
|
let Some(idx) = self.generics.as_ref().and_then(|g| g.type_or_const_param_idx(it)) else {
|
||||||
not_supported!("missing idx in generics");
|
not_supported!("missing idx in generics");
|
||||||
};
|
};
|
||||||
Ok(self
|
Ok(self
|
||||||
|
@ -119,7 +119,7 @@ impl FallibleTypeFolder<Interner> for Filler<'_> {
|
||||||
_outer_binder: DebruijnIndex,
|
_outer_binder: DebruijnIndex,
|
||||||
) -> std::result::Result<Ty, Self::Error> {
|
) -> std::result::Result<Ty, Self::Error> {
|
||||||
let it = from_placeholder_idx(self.db, idx);
|
let it = from_placeholder_idx(self.db, idx);
|
||||||
let Some(idx) = self.generics.as_ref().and_then(|g| g.param_idx(it)) else {
|
let Some(idx) = self.generics.as_ref().and_then(|g| g.type_or_const_param_idx(it)) else {
|
||||||
not_supported!("missing idx in generics");
|
not_supported!("missing idx in generics");
|
||||||
};
|
};
|
||||||
Ok(self
|
Ok(self
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -304,7 +308,11 @@ impl Generics {
|
||||||
};
|
};
|
||||||
|
|
||||||
let lt_iter = self.params.iter_lt().map(from_lt_id(self));
|
let lt_iter = self.params.iter_lt().map(from_lt_id(self));
|
||||||
self.params.iter().map(from_toc_id(self)).chain(lt_iter).chain(self.iter_parent())
|
self.params
|
||||||
|
.iter_type_or_consts()
|
||||||
|
.map(from_toc_id(self))
|
||||||
|
.chain(lt_iter)
|
||||||
|
.chain(self.iter_parent())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate over types and const params without parent params.
|
/// Iterate over types and const params without parent params.
|
||||||
|
@ -336,16 +344,19 @@ impl Generics {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.params.iter().map(from_toc_id(self)).chain(self.params.iter_lt().map(from_lt_id(self)))
|
self.params
|
||||||
|
.iter_type_or_consts()
|
||||||
|
.map(from_toc_id(self))
|
||||||
|
.chain(self.params.iter_lt().map(from_lt_id(self)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator over types and const params of parent.
|
/// Iterator over types and const params of parent.
|
||||||
#[allow(clippy::needless_lifetimes)]
|
pub(crate) fn iter_parent(
|
||||||
pub(crate) fn iter_parent<'a>(
|
&self,
|
||||||
&'a self,
|
) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ {
|
||||||
) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'a>)> + 'a {
|
|
||||||
self.parent_generics().into_iter().flat_map(|it| {
|
self.parent_generics().into_iter().flat_map(|it| {
|
||||||
let from_toc_id = move |(local_id, p): (_, &'a TypeOrConstParamData)| {
|
let from_toc_id = move |(local_id, p)| {
|
||||||
|
let p: &_ = p;
|
||||||
let id = TypeOrConstParamId { parent: it.def, local_id };
|
let id = TypeOrConstParamId { parent: it.def, local_id };
|
||||||
match p {
|
match p {
|
||||||
TypeOrConstParamData::TypeParamData(p) => (
|
TypeOrConstParamData::TypeParamData(p) => (
|
||||||
|
@ -359,14 +370,14 @@ impl Generics {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let from_lt_id = move |(local_id, p): (_, &'a LifetimeParamData)| {
|
let from_lt_id = move |(local_id, p): (_, _)| {
|
||||||
(
|
(
|
||||||
GenericParamId::LifetimeParamId(LifetimeParamId { parent: it.def, local_id }),
|
GenericParamId::LifetimeParamId(LifetimeParamId { parent: it.def, local_id }),
|
||||||
GenericParamDataRef::LifetimeParamData(p),
|
GenericParamDataRef::LifetimeParamData(p),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let lt_iter = it.params.iter_lt().map(from_lt_id);
|
let lt_iter = it.params.iter_lt().map(from_lt_id);
|
||||||
it.params.iter().map(from_toc_id).chain(lt_iter)
|
it.params.iter_type_or_consts().map(from_toc_id).chain(lt_iter)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,7 +394,7 @@ impl Generics {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns number of generic parameter excluding those from parent
|
/// Returns number of generic parameter excluding those from parent
|
||||||
fn len_params(&self) -> usize {
|
fn len_type_and_const_params(&self) -> usize {
|
||||||
self.params.type_or_consts.len()
|
self.params.type_or_consts.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +405,7 @@ impl Generics {
|
||||||
let mut impl_trait_params = 0;
|
let mut impl_trait_params = 0;
|
||||||
let mut const_params = 0;
|
let mut const_params = 0;
|
||||||
let mut lifetime_params = 0;
|
let mut lifetime_params = 0;
|
||||||
self.params.iter().for_each(|(_, data)| match data {
|
self.params.iter_type_or_consts().for_each(|(_, data)| match data {
|
||||||
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
|
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
|
||||||
TypeParamProvenance::TypeParamList => type_params += 1,
|
TypeParamProvenance::TypeParamList => type_params += 1,
|
||||||
TypeParamProvenance::TraitSelf => self_params += 1,
|
TypeParamProvenance::TraitSelf => self_params += 1,
|
||||||
|
@ -409,18 +420,23 @@ impl Generics {
|
||||||
(parent_len, self_params, type_params, const_params, impl_trait_params, lifetime_params)
|
(parent_len, self_params, type_params, const_params, impl_trait_params, lifetime_params)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
|
pub(crate) fn type_or_const_param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
|
||||||
Some(self.find_param(param)?.0)
|
Some(self.find_type_or_const_param(param)?.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_param(&self, param: TypeOrConstParamId) -> Option<(usize, &TypeOrConstParamData)> {
|
fn find_type_or_const_param(
|
||||||
|
&self,
|
||||||
|
param: TypeOrConstParamId,
|
||||||
|
) -> Option<(usize, &TypeOrConstParamData)> {
|
||||||
if param.parent == self.def {
|
if param.parent == self.def {
|
||||||
let (idx, (_local_id, data)) =
|
let idx = param.local_id.into_raw().into_u32() as usize;
|
||||||
self.params.iter().enumerate().find(|(_, (idx, _))| *idx == param.local_id)?;
|
if idx >= self.params.type_or_consts.len() {
|
||||||
Some((idx, data))
|
return None;
|
||||||
|
}
|
||||||
|
Some((idx, &self.params.type_or_consts[param.local_id]))
|
||||||
} else {
|
} else {
|
||||||
self.parent_generics()
|
self.parent_generics()
|
||||||
.and_then(|g| g.find_param(param))
|
.and_then(|g| g.find_type_or_const_param(param))
|
||||||
// Remember that parent parameters come after parameters for self.
|
// Remember that parent parameters come after parameters for self.
|
||||||
.map(|(idx, data)| (self.len_self() + idx, data))
|
.map(|(idx, data)| (self.len_self() + idx, data))
|
||||||
}
|
}
|
||||||
|
@ -432,13 +448,14 @@ impl Generics {
|
||||||
|
|
||||||
fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<(usize, &LifetimeParamData)> {
|
fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<(usize, &LifetimeParamData)> {
|
||||||
if lifetime.parent == self.def {
|
if lifetime.parent == self.def {
|
||||||
let (idx, (_local_id, data)) = self
|
let idx = lifetime.local_id.into_raw().into_u32() as usize;
|
||||||
.params
|
if idx >= self.params.lifetimes.len() {
|
||||||
.iter_lt()
|
return None;
|
||||||
.enumerate()
|
}
|
||||||
.find(|(_, (idx, _))| *idx == lifetime.local_id)?;
|
Some((
|
||||||
|
self.len_type_and_const_params() + idx,
|
||||||
Some((self.len_params() + idx, data))
|
&self.params.lifetimes[lifetime.local_id],
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
self.parent_generics()
|
self.parent_generics()
|
||||||
.and_then(|g| g.find_lifetime(lifetime))
|
.and_then(|g| g.find_lifetime(lifetime))
|
||||||
|
@ -450,6 +467,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,
|
||||||
|
|
|
@ -260,11 +260,11 @@ impl Crate {
|
||||||
doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/")
|
doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cfg(&self, db: &dyn HirDatabase) -> CfgOptions {
|
pub fn cfg(&self, db: &dyn HirDatabase) -> Arc<CfgOptions> {
|
||||||
db.crate_graph()[self.id].cfg_options.clone()
|
db.crate_graph()[self.id].cfg_options.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn potential_cfg(&self, db: &dyn HirDatabase) -> CfgOptions {
|
pub fn potential_cfg(&self, db: &dyn HirDatabase) -> Arc<CfgOptions> {
|
||||||
let data = &db.crate_graph()[self.id];
|
let data = &db.crate_graph()[self.id];
|
||||||
data.potential_cfg_options.clone().unwrap_or_else(|| data.cfg_options.clone())
|
data.potential_cfg_options.clone().unwrap_or_else(|| data.cfg_options.clone())
|
||||||
}
|
}
|
||||||
|
@ -653,7 +653,7 @@ impl Module {
|
||||||
GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id })
|
GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id })
|
||||||
});
|
});
|
||||||
let type_params = generic_params
|
let type_params = generic_params
|
||||||
.iter()
|
.iter_type_or_consts()
|
||||||
.filter(|(_, it)| it.type_param().is_some())
|
.filter(|(_, it)| it.type_param().is_some())
|
||||||
.map(|(local_id, _)| {
|
.map(|(local_id, _)| {
|
||||||
GenericParamId::TypeParamId(TypeParamId::from_unchecked(
|
GenericParamId::TypeParamId(TypeParamId::from_unchecked(
|
||||||
|
|
|
@ -252,7 +252,7 @@ impl Analysis {
|
||||||
Edition::CURRENT,
|
Edition::CURRENT,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
cfg_options.clone(),
|
Arc::new(cfg_options),
|
||||||
None,
|
None,
|
||||||
Env::default(),
|
Env::default(),
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -10,7 +10,6 @@ rust-version.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
tracking = []
|
tracking = []
|
||||||
default = ["tracking"]
|
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
@ -913,12 +913,14 @@ fn project_json_to_crate_graph(
|
||||||
*edition,
|
*edition,
|
||||||
display_name.clone(),
|
display_name.clone(),
|
||||||
version.clone(),
|
version.clone(),
|
||||||
target_cfgs
|
Arc::new(
|
||||||
.iter()
|
target_cfgs
|
||||||
.chain(cfg.iter())
|
.iter()
|
||||||
.chain(iter::once(&r_a_cfg_flag))
|
.chain(cfg.iter())
|
||||||
.cloned()
|
.chain(iter::once(&r_a_cfg_flag))
|
||||||
.collect(),
|
.cloned()
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
None,
|
None,
|
||||||
env,
|
env,
|
||||||
*is_proc_macro,
|
*is_proc_macro,
|
||||||
|
@ -1179,6 +1181,7 @@ fn detached_files_to_crate_graph(
|
||||||
|
|
||||||
let mut cfg_options = create_cfg_options(rustc_cfg);
|
let mut cfg_options = create_cfg_options(rustc_cfg);
|
||||||
cfg_options.insert_atom("rust_analyzer".into());
|
cfg_options.insert_atom("rust_analyzer".into());
|
||||||
|
let cfg_options = Arc::new(cfg_options);
|
||||||
|
|
||||||
for detached_file in detached_files {
|
for detached_file in detached_files {
|
||||||
let file_id = match load(detached_file) {
|
let file_id = match load(detached_file) {
|
||||||
|
@ -1380,8 +1383,8 @@ fn add_target_crate_root(
|
||||||
edition,
|
edition,
|
||||||
Some(display_name),
|
Some(display_name),
|
||||||
Some(pkg.version.to_string()),
|
Some(pkg.version.to_string()),
|
||||||
cfg_options,
|
Arc::new(cfg_options),
|
||||||
potential_cfg_options,
|
potential_cfg_options.map(Arc::new),
|
||||||
env,
|
env,
|
||||||
matches!(kind, TargetKind::Lib { is_proc_macro: true }),
|
matches!(kind, TargetKind::Lib { is_proc_macro: true }),
|
||||||
origin,
|
origin,
|
||||||
|
@ -1437,7 +1440,7 @@ fn sysroot_to_crate_graph(
|
||||||
let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag("test".into())]).unwrap();
|
let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag("test".into())]).unwrap();
|
||||||
for (cid, c) in cg.iter_mut() {
|
for (cid, c) in cg.iter_mut() {
|
||||||
// uninject `test` flag so `core` keeps working.
|
// uninject `test` flag so `core` keeps working.
|
||||||
c.cfg_options.apply_diff(diff.clone());
|
Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone());
|
||||||
// patch the origin
|
// patch the origin
|
||||||
if c.origin.is_local() {
|
if c.origin.is_local() {
|
||||||
let lang_crate = LangCrateOrigin::from(
|
let lang_crate = LangCrateOrigin::from(
|
||||||
|
@ -1486,7 +1489,7 @@ fn sysroot_to_crate_graph(
|
||||||
(SysrootPublicDeps { deps: pub_deps }, libproc_macro)
|
(SysrootPublicDeps { deps: pub_deps }, libproc_macro)
|
||||||
}
|
}
|
||||||
SysrootMode::Stitched(stitched) => {
|
SysrootMode::Stitched(stitched) => {
|
||||||
let cfg_options = create_cfg_options(rustc_cfg);
|
let cfg_options = Arc::new(create_cfg_options(rustc_cfg));
|
||||||
let sysroot_crates: FxHashMap<SysrootCrate, CrateId> = stitched
|
let sysroot_crates: FxHashMap<SysrootCrate, CrateId> = stitched
|
||||||
.crates()
|
.crates()
|
||||||
.filter_map(|krate| {
|
.filter_map(|krate| {
|
||||||
|
|
|
@ -280,7 +280,9 @@ impl flags::AnalysisStats {
|
||||||
let mut fail = 0;
|
let mut fail = 0;
|
||||||
for &a in adts {
|
for &a in adts {
|
||||||
let generic_params = db.generic_params(a.into());
|
let generic_params = db.generic_params(a.into());
|
||||||
if generic_params.iter().next().is_some() || generic_params.iter_lt().next().is_some() {
|
if generic_params.iter_type_or_consts().next().is_some()
|
||||||
|
|| generic_params.iter_lt().next().is_some()
|
||||||
|
{
|
||||||
// Data types with generics don't have layout.
|
// Data types with generics don't have layout.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,8 +189,8 @@ impl ChangeFixture {
|
||||||
meta.edition,
|
meta.edition,
|
||||||
Some(crate_name.clone().into()),
|
Some(crate_name.clone().into()),
|
||||||
version,
|
version,
|
||||||
meta.cfg.clone(),
|
From::from(meta.cfg.clone()),
|
||||||
Some(meta.cfg),
|
Some(From::from(meta.cfg)),
|
||||||
meta.env,
|
meta.env,
|
||||||
false,
|
false,
|
||||||
origin,
|
origin,
|
||||||
|
@ -227,8 +227,8 @@ impl ChangeFixture {
|
||||||
Edition::CURRENT,
|
Edition::CURRENT,
|
||||||
Some(CrateName::new("test").unwrap().into()),
|
Some(CrateName::new("test").unwrap().into()),
|
||||||
None,
|
None,
|
||||||
default_cfg.clone(),
|
From::from(default_cfg.clone()),
|
||||||
Some(default_cfg),
|
Some(From::from(default_cfg)),
|
||||||
default_env,
|
default_env,
|
||||||
false,
|
false,
|
||||||
CrateOrigin::Local { repo: None, name: None },
|
CrateOrigin::Local { repo: None, name: None },
|
||||||
|
|
Loading…
Reference in a new issue