Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/base-db/src/input.rs8
-rw-r--r--crates/hir-def/src/data.rs2
-rw-r--r--crates/hir-def/src/data/adt.rs11
-rw-r--r--crates/hir-def/src/expander.rs11
-rw-r--r--crates/hir-def/src/generics.rs30
-rw-r--r--crates/hir-ty/src/consteval.rs33
-rw-r--r--crates/hir-ty/src/display.rs6
-rw-r--r--crates/hir-ty/src/infer.rs6
-rw-r--r--crates/hir-ty/src/infer/cast.rs4
-rw-r--r--crates/hir-ty/src/infer/closure.rs20
-rw-r--r--crates/hir-ty/src/infer/expr.rs20
-rw-r--r--crates/hir-ty/src/infer/pat.rs48
-rw-r--r--crates/hir-ty/src/lib.rs8
-rw-r--r--crates/hir-ty/src/lower.rs132
-rw-r--r--crates/hir-ty/src/mir/lower.rs8
-rw-r--r--crates/hir-ty/src/mir/monomorphization.rs4
-rw-r--r--crates/hir-ty/src/utils.rs73
-rw-r--r--crates/hir/src/lib.rs6
-rw-r--r--crates/ide/src/lib.rs2
-rw-r--r--crates/limit/Cargo.toml3
-rw-r--r--crates/project-model/src/workspace.rs23
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs4
-rw-r--r--crates/test-fixture/src/lib.rs8
23 files changed, 243 insertions, 227 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index 27eb05cd4d..1924ce578a 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -285,9 +285,9 @@ pub struct CrateData {
/// For purposes of analysis, crates are anonymous (only names in
/// `Dependency` matters), this name should only be used for UI.
pub display_name: Option<CrateDisplayName>,
- pub cfg_options: CfgOptions,
+ pub cfg_options: Arc<CfgOptions>,
/// 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 dependencies: Vec<Dependency>,
pub origin: CrateOrigin,
@@ -328,8 +328,8 @@ impl CrateGraph {
edition: Edition,
display_name: Option<CrateDisplayName>,
version: Option<String>,
- cfg_options: CfgOptions,
- potential_cfg_options: Option<CfgOptions>,
+ cfg_options: Arc<CfgOptions>,
+ potential_cfg_options: Option<Arc<CfgOptions>>,
env: Env,
is_proc_macro: bool,
origin: CrateOrigin,
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index da790f1151..b5317be288 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -737,7 +737,7 @@ impl<'a> AssocItemCollector<'a> {
&AstIdWithPath::new(file_id, ast_id, Clone::clone(path)),
ctxt,
expand_to,
- self.expander.module.krate(),
+ self.expander.krate(),
resolver,
) {
Ok(Some(call_id)) => {
diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs
index a7461b78af..5330db7c80 100644
--- a/crates/hir-def/src/data/adt.rs
+++ b/crates/hir-def/src/data/adt.rs
@@ -191,8 +191,6 @@ impl StructData {
let krate = loc.container.krate;
let item_tree = loc.id.item_tree(db);
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 mut flags = StructFlags::NO_FLAGS;
@@ -219,7 +217,7 @@ impl StructData {
loc.id.file_id(),
loc.container.local_id,
&item_tree,
- &cfg_options,
+ &db.crate_graph()[krate].cfg_options,
&strukt.fields,
None,
);
@@ -248,8 +246,6 @@ impl StructData {
let krate = loc.container.krate;
let item_tree = loc.id.item_tree(db);
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 mut flags = StructFlags::NO_FLAGS;
if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() {
@@ -266,7 +262,7 @@ impl StructData {
loc.id.file_id(),
loc.container.local_id,
&item_tree,
- &cfg_options,
+ &db.crate_graph()[krate].cfg_options,
&union.fields,
None,
);
@@ -338,7 +334,6 @@ impl EnumVariantData {
let container = loc.parent.lookup(db).container;
let krate = container.krate;
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 (var_data, diagnostics) = lower_fields(
@@ -347,7 +342,7 @@ impl EnumVariantData {
loc.id.file_id(),
container.local_id,
&item_tree,
- &cfg_options,
+ &db.crate_graph()[krate].cfg_options,
&variant.fields,
Some(item_tree[loc.parent.lookup(db).id.value].visibility),
);
diff --git a/crates/hir-def/src/expander.rs b/crates/hir-def/src/expander.rs
index b0872fcdc0..73ce942c58 100644
--- a/crates/hir-def/src/expander.rs
+++ b/crates/hir-def/src/expander.rs
@@ -11,6 +11,7 @@ use hir_expand::{
};
use limit::Limit;
use syntax::{ast, Parse};
+use triomphe::Arc;
use crate::{
attr::Attrs, db::DefDatabase, lower::LowerCtx, path::Path, AsMacroCall, MacroId, ModuleId,
@@ -19,9 +20,8 @@ use crate::{
#[derive(Debug)]
pub struct Expander {
- cfg_options: CfgOptions,
+ cfg_options: Arc<CfgOptions>,
span_map: OnceCell<SpanMap>,
- krate: CrateId,
current_file_id: HirFileId,
pub(crate) module: ModuleId,
/// `recursion_depth == usize::MAX` indicates that the recursion limit has been reached.
@@ -45,10 +45,13 @@ impl Expander {
recursion_limit,
cfg_options: db.crate_graph()[module.krate].cfg_options.clone(),
span_map: OnceCell::new(),
- krate: module.krate,
}
}
+ pub fn krate(&self) -> CrateId {
+ self.module.krate
+ }
+
pub fn enter_expand<T: ast::AstNode>(
&mut self,
db: &dyn DefDatabase,
@@ -112,7 +115,7 @@ impl Expander {
pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::HasAttrs) -> Attrs {
Attrs::filter(
db,
- self.krate,
+ self.krate(),
RawAttrs::new(
db.upcast(),
owner,
diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs
index 118055b605..acc60e1d9e 100644
--- a/crates/hir-def/src/generics.rs
+++ b/crates/hir-def/src/generics.rs
@@ -3,13 +3,15 @@
//! generic parameters. See also the `Generics` type and the `generics_of` query
//! in rustc.
+use std::ops;
+
use either::Either;
use hir_expand::{
name::{AsName, Name},
ExpandResult,
};
use intern::Interned;
-use la_arena::{Arena, Idx};
+use la_arena::Arena;
use once_cell::unsync::Lazy;
use stdx::impl_from;
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
@@ -23,7 +25,7 @@ use crate::{
nameres::{DefMap, MacroSubNs},
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
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, ...).
@@ -158,6 +160,20 @@ pub struct GenericParams {
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
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
/// It might still result in multiple actual predicates though, because of
@@ -199,7 +215,7 @@ impl GenericParamsCollector {
lower_ctx: &LowerCtx<'_>,
node: &dyn HasGenericParams,
add_param_attrs: impl FnMut(
- Either<Idx<TypeOrConstParamData>, Idx<LifetimeParamData>>,
+ Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
ast::GenericParam,
),
) {
@@ -227,7 +243,7 @@ impl GenericParamsCollector {
lower_ctx: &LowerCtx<'_>,
params: ast::GenericParamList,
mut add_param_attrs: impl FnMut(
- Either<Idx<TypeOrConstParamData>, Idx<LifetimeParamData>>,
+ Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
ast::GenericParam,
),
) {
@@ -416,16 +432,16 @@ impl GenericParams {
}
/// Iterator of type_or_consts field
- pub fn iter(
+ pub fn iter_type_or_consts(
&self,
- ) -> impl DoubleEndedIterator<Item = (Idx<TypeOrConstParamData>, &TypeOrConstParamData)> {
+ ) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> {
self.type_or_consts.iter()
}
/// Iterator of lifetimes field
pub fn iter_lt(
&self,
- ) -> impl DoubleEndedIterator<Item = (Idx<LifetimeParamData>, &LifetimeParamData)> {
+ ) -> impl DoubleEndedIterator<Item = (LocalLifetimeParamId, &LifetimeParamData)> {
self.lifetimes.iter()
}
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index 705609ba68..f09277a92e 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -77,30 +77,32 @@ pub(crate) fn path_to_const(
resolver: &Resolver,
path: &Path,
mode: ParamLoweringMode,
- args_lazy: impl FnOnce() -> Generics,
+ args: impl FnOnce() -> Option<Generics>,
debruijn: DebruijnIndex,
expected_ty: Ty,
) -> Option<Const> {
match resolver.resolve_path_in_value_ns_fully(db.upcast(), path) {
Some(ValueNs::GenericParam(p)) => {
let ty = db.const_param_ty(p);
- let args = args_lazy();
let value = match mode {
ParamLoweringMode::Placeholder => {
ConstValue::Placeholder(to_placeholder_idx(db, p.into()))
}
- ParamLoweringMode::Variable => match args.param_idx(p.into()) {
- Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
- None => {
- never!(
- "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
- args,
- path,
- p
- );
- return None;
+ ParamLoweringMode::Variable => {
+ let args = args();
+ match args.as_ref().and_then(|args| args.type_or_const_param_idx(p.into())) {
+ Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
+ None => {
+ never!(
+ "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
+ args,
+ path,
+ p
+ );
+ return None;
+ }
}
- },
+ }
};
Some(ConstData { ty, value }.intern(Interner))
}
@@ -285,7 +287,6 @@ pub(crate) fn eval_to_const(
expr: ExprId,
mode: ParamLoweringMode,
ctx: &mut InferenceContext<'_>,
- args: impl FnOnce() -> Generics,
debruijn: DebruijnIndex,
) -> Const {
let db = ctx.db;
@@ -304,7 +305,9 @@ pub(crate) fn eval_to_const(
}
if let Expr::Path(p) = &ctx.body.exprs[expr] {
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;
}
}
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index eb7f106cdf..22a52e6a23 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -453,7 +453,7 @@ impl HirDisplay for Const {
ConstValue::Placeholder(idx) => {
let id = from_placeholder_idx(f.db, *idx);
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()))?;
Ok(())
}
@@ -1176,7 +1176,7 @@ impl HirDisplay for Ty {
TyKind::Placeholder(idx) => {
let id = from_placeholder_idx(db, *idx);
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 {
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
@@ -1724,7 +1724,7 @@ impl HirDisplay for LifetimeData {
LifetimeData::Placeholder(idx) => {
let id = lt_from_placeholder_idx(f.db, *idx);
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()))?;
Ok(())
}
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 3b644379fa..3aacf7d07f 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -60,7 +60,7 @@ use crate::{
lower::ImplTraitLoweringMode,
to_assoc_type_id,
traits::FnTrait,
- utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
+ utils::{Generics, InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId,
ImplTraitIdx, InEnvironment, Interner, Lifetime, OpaqueTyId, ProjectionTy, Substitution,
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
// `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
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs
index f8c03ee288..060b5f36f2 100644
--- a/crates/hir-ty/src/infer/cast.rs
+++ b/crates/hir-ty/src/infer/cast.rs
@@ -19,10 +19,6 @@ impl CastCheck {
let expr_ty = table.resolve_ty_shallow(&self.expr_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() {
return;
}
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 20d24e6fe2..a25498eff3 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -26,7 +26,7 @@ use crate::{
mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem},
to_chalk_trait_id,
traits::FnTrait,
- utils::{self, elaborate_clause_supertraits, generics, Generics},
+ utils::{self, elaborate_clause_supertraits, Generics},
Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy,
DynTyExt, FnAbi, FnPointer, FnSig, Interner, OpaqueTy, ProjectionTyExt, Substitution, Ty,
TyExt, WhereClause,
@@ -331,14 +331,10 @@ impl CapturedItemWithoutTy {
place: self.place,
kind: self.kind,
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(
- db: &dyn HirDatabase,
- owner: DefWithBodyId,
- ty: Ty,
- ) -> Binders<Ty> {
+ fn replace_placeholder_with_binder(ctx: &mut InferenceContext<'_>, ty: Ty) -> Binders<Ty> {
struct Filler<'a> {
db: &'a dyn HirDatabase,
generics: Generics,
@@ -361,7 +357,7 @@ impl CapturedItemWithoutTy {
outer_binder: DebruijnIndex,
) -> Result<chalk_ir::Const<Interner>, Self::Error> {
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(());
};
Ok(BoundVar::new(outer_binder, idx).to_const(Interner, ty))
@@ -373,18 +369,18 @@ impl CapturedItemWithoutTy {
outer_binder: DebruijnIndex,
) -> std::result::Result<Ty, Self::Error> {
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(());
};
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);
};
- 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);
- make_binders(db, &filler.generics, result)
+ make_binders(ctx.db, &filler.generics, result)
}
}
}
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 4d3d7376c4..d011a62e77 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -1040,18 +1040,12 @@ impl InferenceContext<'_> {
(
elem_ty,
- if let Some(g_def) = self.owner.as_generic_def_id() {
- let generics = generics(self.db.upcast(), g_def);
- consteval::eval_to_const(
- repeat,
- ParamLoweringMode::Placeholder,
- self,
- || generics,
- DebruijnIndex::INNERMOST,
- )
- } else {
- consteval::usize_const(self.db, None, krate)
- },
+ consteval::eval_to_const(
+ repeat,
+ ParamLoweringMode::Placeholder,
+ self,
+ DebruijnIndex::INNERMOST,
+ ),
)
}
};
@@ -1852,7 +1846,7 @@ impl InferenceContext<'_> {
ty,
c,
ParamLoweringMode::Placeholder,
- || generics(this.db.upcast(), this.resolver.generic_def().unwrap()),
+ || this.generics(),
DebruijnIndex::INNERMOST,
)
},
diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs
index 440ffa3357..1b354935a5 100644
--- a/crates/hir-ty/src/infer/pat.rs
+++ b/crates/hir-ty/src/infer/pat.rs
@@ -2,13 +2,13 @@
use std::iter::repeat_with;
-use chalk_ir::Mutability;
use hir_def::{
body::Body,
hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId},
path::Path,
};
use hir_expand::name::Name;
+use stdx::TupleExt;
use crate::{
consteval::{try_const_usize, usize_const},
@@ -16,8 +16,8 @@ use crate::{
infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
lower::lower_to_chalk_mutability,
primitive::UintTy,
- static_lifetime, InferenceDiagnostic, Interner, Scalar, Substitution, Ty, TyBuilder, TyExt,
- TyKind,
+ static_lifetime, InferenceDiagnostic, Interner, Mutability, Scalar, Substitution, Ty,
+ TyBuilder, TyExt, TyKind,
};
/// Used to generalize patterns and assignee expressions.
@@ -90,9 +90,6 @@ impl InferenceContext<'_> {
self.unify(&ty, expected);
- let substs =
- ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
-
match def {
_ if subs.is_empty() => {}
Some(def) => {
@@ -109,8 +106,10 @@ impl InferenceContext<'_> {
let pre_iter = pre.iter().enumerate();
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) {
- let field_def = {
+ let expected_ty = {
match variant_data.field(&Name::new_tuple_field(i)) {
Some(local_id) => {
if !visibilities[local_id]
@@ -118,17 +117,17 @@ impl InferenceContext<'_> {
{
// 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);
}
}
@@ -159,9 +158,6 @@ impl InferenceContext<'_> {
self.unify(&ty, expected);
- let substs =
- ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
-
match def {
_ if subs.len() == 0 => {}
Some(def) => {
@@ -169,8 +165,10 @@ impl InferenceContext<'_> {
let variant_data = def.variant_data(self.db.upcast());
let visibilities = self.db.field_visibilities(def);
+ let substs = ty.as_adt().map(TupleExt::tail);
+
for (name, inner) in subs {
- let field_def = {
+ let expected_ty = {
match variant_data.field(&name) {
Some(local_id) => {
if !visibilities[local_id]
@@ -181,23 +179,23 @@ impl InferenceContext<'_> {
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 => {
self.push_diagnostic(InferenceDiagnostic::NoSuchField {
field: inner.into(),
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);
}
}
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index ad8202d4d2..b12ccf7c83 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -288,7 +288,7 @@ impl Hash for ConstScalar {
/// 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> {
- 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>
@@ -603,15 +603,17 @@ pub enum ImplTraitId {
}
impl_intern_value_trivial!(ImplTraitId);
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+#[derive(PartialEq, Eq, Debug, Hash)]
pub struct ImplTraits {
pub(crate) impl_traits: Arena<ImplTrait>,
}
has_interner!(ImplTraits);
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+#[derive(PartialEq, Eq, Debug, Hash)]
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>>,
}
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 9a468e2a23..bfc84ee5e3 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -62,8 +62,8 @@ use crate::{
mapping::{from_chalk_trait_id, lt_to_placeholder_idx, ToChalk},
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
utils::{
- all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
- InTypeConstIdMetadata,
+ self, all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
+ Generics, InTypeConstIdMetadata,
},
AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
FnAbi, FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime,
@@ -245,13 +245,8 @@ impl<'a> TyLoweringContext<'a> {
)
}
- fn generics(&self) -> Generics {
- generics(
- self.db.upcast(),
- self.resolver
- .generic_def()
- .expect("there should be generics if there's a generic param"),
- )
+ fn generics(&self) -> Option<Generics> {
+ Some(generics(self.db.upcast(), self.resolver.generic_def()?))
}
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
// lowering the bounds
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're currently in, because they don't end up inside
@@ -352,8 +347,7 @@ impl<'a> TyLoweringContext<'a> {
let idx = counter.get();
// FIXME we're probably doing something wrong here
counter.set(idx + count_impl_traits(type_ref) as u16);
- if let Some(def) = self.resolver.generic_def() {
- let generics = generics(self.db.upcast(), def);
+ if let Some(generics) = self.generics() {
let param = generics
.iter()
.filter(|(_, data)| {
@@ -388,8 +382,7 @@ impl<'a> TyLoweringContext<'a> {
const_params,
_impl_trait_params,
_lifetime_params,
- ) = if let Some(def) = self.resolver.generic_def() {
- let generics = generics(self.db.upcast(), def);
+ ) = if let Some(generics) = self.generics() {
generics.provenance_split()
} else {
(0, 0, 0, 0, 0, 0)
@@ -577,44 +570,40 @@ impl<'a> TyLoweringContext<'a> {
// FIXME(trait_alias): Implement trait alias.
return (TyKind::Error.intern(Interner), None);
}
- TypeNs::GenericParam(param_id) => {
- let generics = generics(
- self.db.upcast(),
- self.resolver.generic_def().expect("generics in scope"),
- );
- match self.type_param_mode {
- ParamLoweringMode::Placeholder => {
- TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
- }
- ParamLoweringMode::Variable => {
- let idx = match generics.param_idx(param_id.into()) {
- None => {
- never!("no matching generics");
- return (TyKind::Error.intern(Interner), None);
- }
- Some(idx) => idx,
- };
+ TypeNs::GenericParam(param_id) => match self.type_param_mode {
+ ParamLoweringMode::Placeholder => {
+ TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
+ }
+ ParamLoweringMode::Variable => {
+ let idx = match self
+ .generics()
+ .expect("generics in scope")
+ .type_or_const_param_idx(param_id.into())
+ {
+ None => {
+ never!("no matching generics");
+ return (TyKind::Error.intern(Interner), None);
+ }
+ 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) => {
- let def =
- self.resolver.generic_def().expect("impl should have generic param scope");
- let generics = generics(self.db.upcast(), def);
+ let generics = self.generics().expect("impl should have generic param scope");
match self.type_param_mode {
ParamLoweringMode::Placeholder => {
// `def` can be either impl itself or item within, and we need impl itself
// now.
- let generics = generics.parent_generics().unwrap_or(&generics);
+ let generics = generics.parent_or_self();
let subst = generics.placeholder_subst(self.db);
self.db.impl_self_ty(impl_id).substitute(Interner, &subst)
}
ParamLoweringMode::Variable => {
- let starting_from = match def {
+ let starting_from = match generics.def() {
GenericDefId::ImplId(_) => 0,
// `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
@@ -682,12 +671,12 @@ impl<'a> TyLoweringContext<'a> {
}
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);
};
let ty = named_associated_type_shorthand_candidates(
self.db,
- def,
+ generics.def(),
res,
Some(segment.name.clone()),
move |name, t, associated_ty| {
@@ -699,7 +688,6 @@ impl<'a> TyLoweringContext<'a> {
let parent_subst = match self.type_param_mode {
ParamLoweringMode::Placeholder => {
// 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);
s.apply(parent_subst, Interner)
}
@@ -721,7 +709,7 @@ impl<'a> TyLoweringContext<'a> {
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(
Interner,
@@ -1019,46 +1007,43 @@ impl<'a> TyLoweringContext<'a> {
self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
}
- pub(crate) fn lower_where_predicate(
- &self,
- where_predicate: &WherePredicate,
+ pub(crate) fn lower_where_predicate<'b>(
+ &'b self,
+ where_predicate: &'b WherePredicate,
ignore_bindings: bool,
- ) -> impl Iterator<Item = QuantifiedWhereClause> {
+ ) -> impl Iterator<Item = QuantifiedWhereClause> + 'b {
match where_predicate {
WherePredicate::ForLifetime { target, bound, .. }
| WherePredicate::TypeBound { target, bound } => {
let self_ty = match target {
WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
- WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
- let generic_def = self.resolver.generic_def().expect("generics in scope");
- let generics = generics(self.db.upcast(), generic_def);
- let param_id = hir_def::TypeOrConstParamId {
- parent: generic_def,
- local_id: *param_id,
- };
- let placeholder = to_placeholder_idx(self.db, param_id);
+ &WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
+ let def = self.resolver.generic_def().expect("generics in scope");
+ let param_id = hir_def::TypeOrConstParamId { parent: def, local_id };
match self.type_param_mode {
- ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
+ ParamLoweringMode::Placeholder => {
+ TyKind::Placeholder(to_placeholder_idx(self.db, param_id))
+ }
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))
}
}
.intern(Interner)
}
};
- self.lower_type_bound(bound, self_ty, ignore_bindings)
- .collect::<Vec<_>>()
- .into_iter()
+ Either::Left(self.lower_type_bound(bound, self_ty, ignore_bindings))
}
- WherePredicate::Lifetime { bound, target } => {
- vec![crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives {
+ WherePredicate::Lifetime { bound, target } => Either::Right(iter::once(
+ crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives {
a: self.lower_lifetime(bound),
b: self.lower_lifetime(target),
- }))]
- .into_iter()
- }
+ })),
+ )),
}
+ .into_iter()
}
pub(crate) fn lower_type_bound(
@@ -1218,8 +1203,8 @@ impl<'a> TyLoweringContext<'a> {
});
if let Some(target_param_idx) = target_param_idx {
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
// the target of our `bound`.
// Our counter within `impl_trait_mode` should be that number
@@ -1393,8 +1378,8 @@ impl<'a> TyLoweringContext<'a> {
crate::wrap_empty_binders(clause)
});
predicates.extend(sized_clause);
- predicates.shrink_to_fit();
}
+ predicates.shrink_to_fit();
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))
}
ParamLoweringMode::Variable => {
- let generics = generics(
- self.db.upcast(),
- self.resolver.generic_def().expect("generics in scope"),
- );
+ let generics = self.generics().expect("generics in scope");
let idx = match generics.lifetime_idx(id) {
None => return error_lifetime(),
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
if let GenericDefId::TraitId(trait_id) = param_id.parent() {
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 starting_idx = match def {
GenericDefId::TraitId(_) => 0,
@@ -2258,7 +2240,7 @@ pub(crate) fn const_or_path_to_chalk(
expected_ty: Ty,
value: &ConstRef,
mode: ParamLoweringMode,
- args: impl FnOnce() -> Generics,
+ args: impl FnOnce() -> Option<Generics>,
debruijn: DebruijnIndex,
) -> Const {
match value {
@@ -2277,7 +2259,7 @@ pub(crate) fn const_or_path_to_chalk(
.unwrap_or_else(|| unknown_const(expected_ty))
}
&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()
{
// FIXME: current `InTypeConstId` is very unstable, so we only use it in non local crate
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index ea311cadb7..c65dfd3285 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -495,9 +495,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
ty,
value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
DebruijnIndex::INNERMOST,
- gen.param_idx(p.into()).ok_or(MirLowerError::TypeError(
- "fail to lower const generic param",
- ))?,
+ gen.type_or_const_param_idx(p.into()).ok_or(
+ MirLowerError::TypeError(
+ "fail to lower const generic param",
+ ),
+ )?,
)),
}
.intern(Interner),
diff --git a/crates/hir-ty/src/mir/monomorphization.rs b/crates/hir-ty/src/mir/monomorphization.rs
index d6557c3a81..a384c9306e 100644
--- a/crates/hir-ty/src/mir/monomorphization.rs
+++ b/crates/hir-ty/src/mir/monomorphization.rs
@@ -101,7 +101,7 @@ impl FallibleTypeFolder<Interner> for Filler<'_> {
_outer_binder: DebruijnIndex,
) -> std::result::Result<chalk_ir::Const<Interner>, Self::Error> {
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");
};
Ok(self
@@ -119,7 +119,7 @@ impl FallibleTypeFolder<Interner> for Filler<'_> {
_outer_binder: DebruijnIndex,
) -> std::result::Result<Ty, Self::Error> {
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");
};
Ok(self
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index afd4d1f271..42c7a84032 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -262,7 +262,7 @@ impl<'a> ClosureSubst<'a> {
}
}
-#[derive(Debug)]
+#[derive(Clone, Debug)]
pub(crate) struct Generics {
def: GenericDefId,
pub(crate) params: Interned<GenericParams>,
@@ -274,6 +274,10 @@ impl Generics {
self.iter().map(|(id, _)| id)
}
+ pub(crate) fn def(&self) -> GenericDefId {
+ self.def
+ }
+
/// Iterator over types and const params of self, then parent.
pub(crate) fn iter<'a>(
&'a self,
@@ -304,7 +308,11 @@ impl Generics {
};
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.
@@ -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.
- #[allow(clippy::needless_lifetimes)]
- pub(crate) fn iter_parent<'a>(
- &'a self,
- ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'a>)> + 'a {
+ pub(crate) fn iter_parent(
+ &self,
+ ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ {
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 };
match 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 }),
GenericParamDataRef::LifetimeParamData(p),
)
};
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
- fn len_params(&self) -> usize {
+ fn len_type_and_const_params(&self) -> usize {
self.params.type_or_consts.len()
}
@@ -394,7 +405,7 @@ impl Generics {
let mut impl_trait_params = 0;
let mut const_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 {
TypeParamProvenance::TypeParamList => type_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)
}
- pub(crate) fn param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
- Some(self.find_param(param)?.0)
+ pub(crate) fn type_or_const_param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
+ 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 {
- let (idx, (_local_id, data)) =
- self.params.iter().enumerate().find(|(_, (idx, _))| *idx == param.local_id)?;
- Some((idx, data))
+ let idx = param.local_id.into_raw().into_u32() as usize;
+ if idx >= self.params.type_or_consts.len() {
+ return None;
+ }
+ Some((idx, &self.params.type_or_consts[param.local_id]))
} else {
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.
.map(|(idx, data)| (self.len_self() + idx, data))
}
@@ -432,13 +448,14 @@ impl Generics {
fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<(usize, &LifetimeParamData)> {
if lifetime.parent == self.def {
- let (idx, (_local_id, data)) = self
- .params
- .iter_lt()
- .enumerate()
- .find(|(_, (idx, _))| *idx == lifetime.local_id)?;
-
- Some((self.len_params() + idx, data))
+ let idx = lifetime.local_id.into_raw().into_u32() as usize;
+ if idx >= self.params.lifetimes.len() {
+ return None;
+ }
+ Some((
+ self.len_type_and_const_params() + idx,
+ &self.params.lifetimes[lifetime.local_id],
+ ))
} else {
self.parent_generics()
.and_then(|g| g.find_lifetime(lifetime))
@@ -450,6 +467,10 @@ impl Generics {
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.
pub(crate) fn bound_vars_subst(
&self,
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 9b9f710d9a..8556d35a43 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -260,11 +260,11 @@ impl Crate {
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()
}
- 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];
data.potential_cfg_options.clone().unwrap_or_else(|| data.cfg_options.clone())
}
@@ -653,7 +653,7 @@ impl Module {
GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id })
});
let type_params = generic_params
- .iter()
+ .iter_type_or_consts()
.filter(|(_, it)| it.type_param().is_some())
.map(|(local_id, _)| {
GenericParamId::TypeParamId(TypeParamId::from_unchecked(
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index ad48d80389..e13060e4d7 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -252,7 +252,7 @@ impl Analysis {
Edition::CURRENT,
None,
None,
- cfg_options.clone(),
+ Arc::new(cfg_options),
None,
Env::default(),
false,
diff --git a/crates/limit/Cargo.toml b/crates/limit/Cargo.toml
index c89722cc40..c1a768833b 100644
--- a/crates/limit/Cargo.toml
+++ b/crates/limit/Cargo.toml
@@ -10,7 +10,6 @@ rust-version.workspace = true
[features]
tracking = []
-default = ["tracking"]
[lints]
-workspace = true \ No newline at end of file
+workspace = true
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index b59c0d59e4..00e9c12988 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -913,12 +913,14 @@ fn project_json_to_crate_graph(
*edition,
display_name.clone(),
version.clone(),
- target_cfgs
- .iter()
- .chain(cfg.iter())
- .chain(iter::once(&r_a_cfg_flag))
- .cloned()
- .collect(),
+ Arc::new(
+ target_cfgs
+ .iter()
+ .chain(cfg.iter())
+ .chain(iter::once(&r_a_cfg_flag))
+ .cloned()
+ .collect(),
+ ),
None,
env,
*is_proc_macro,
@@ -1179,6 +1181,7 @@ fn detached_files_to_crate_graph(
let mut cfg_options = create_cfg_options(rustc_cfg);
cfg_options.insert_atom("rust_analyzer".into());
+ let cfg_options = Arc::new(cfg_options);
for detached_file in detached_files {
let file_id = match load(detached_file) {
@@ -1380,8 +1383,8 @@ fn add_target_crate_root(
edition,
Some(display_name),
Some(pkg.version.to_string()),
- cfg_options,
- potential_cfg_options,
+ Arc::new(cfg_options),
+ potential_cfg_options.map(Arc::new),
env,
matches!(kind, TargetKind::Lib { is_proc_macro: true }),
origin,
@@ -1437,7 +1440,7 @@ fn sysroot_to_crate_graph(
let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag("test".into())]).unwrap();
for (cid, c) in cg.iter_mut() {
// 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
if c.origin.is_local() {
let lang_crate = LangCrateOrigin::from(
@@ -1486,7 +1489,7 @@ fn sysroot_to_crate_graph(
(SysrootPublicDeps { deps: pub_deps }, libproc_macro)
}
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
.crates()
.filter_map(|krate| {
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index fdd77199aa..a1eea8839e 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -280,7 +280,9 @@ impl flags::AnalysisStats {
let mut fail = 0;
for &a in adts {
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.
continue;
}
diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs
index c8d785f83e..7ce83078cb 100644
--- a/crates/test-fixture/src/lib.rs
+++ b/crates/test-fixture/src/lib.rs
@@ -189,8 +189,8 @@ impl ChangeFixture {
meta.edition,
Some(crate_name.clone().into()),
version,
- meta.cfg.clone(),
- Some(meta.cfg),
+ From::from(meta.cfg.clone()),
+ Some(From::from(meta.cfg)),
meta.env,
false,
origin,
@@ -227,8 +227,8 @@ impl ChangeFixture {
Edition::CURRENT,
Some(CrateName::new("test").unwrap().into()),
None,
- default_cfg.clone(),
- Some(default_cfg),
+ From::from(default_cfg.clone()),
+ Some(From::from(default_cfg)),
default_env,
false,
CrateOrigin::Local { repo: None, name: None },