Skip to content

Commit c0ddcc9

Browse files
committed
Lower const params with a bad id
1 parent 76d8650 commit c0ddcc9

35 files changed

+412
-192
lines changed

crates/base-db/src/fixture.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ impl ChangeFixture {
215215
None,
216216
default_cfg,
217217
Default::default(),
218-
Env::default(),
218+
Env::new_for_test_fixture(),
219219
false,
220220
CrateOrigin::Local { repo: None, name: None },
221221
default_target_data_layout
@@ -259,7 +259,7 @@ impl ChangeFixture {
259259
None,
260260
Default::default(),
261261
Default::default(),
262-
Env::default(),
262+
Env::new_for_test_fixture(),
263263
false,
264264
CrateOrigin::Lang(LangCrateOrigin::Core),
265265
target_layout.clone(),
@@ -298,7 +298,7 @@ impl ChangeFixture {
298298
None,
299299
Default::default(),
300300
Default::default(),
301-
Env::default(),
301+
Env::new_for_test_fixture(),
302302
true,
303303
CrateOrigin::Local { repo: None, name: None },
304304
target_layout,

crates/base-db/src/input.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ pub enum CrateOrigin {
151151
Lang(LangCrateOrigin),
152152
}
153153

154+
impl CrateOrigin {
155+
pub fn is_local(&self) -> bool {
156+
matches!(self, CrateOrigin::Local { .. })
157+
}
158+
}
159+
154160
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
155161
pub enum LangCrateOrigin {
156162
Alloc,
@@ -333,6 +339,17 @@ pub struct Env {
333339
entries: FxHashMap<String, String>,
334340
}
335341

342+
impl Env {
343+
pub fn new_for_test_fixture() -> Self {
344+
Env {
345+
entries: FxHashMap::from_iter([(
346+
String::from("__ra_is_test_fixture"),
347+
String::from("__ra_is_test_fixture"),
348+
)]),
349+
}
350+
}
351+
}
352+
336353
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
337354
pub struct Dependency {
338355
pub crate_id: CrateId,

crates/hir-def/src/body.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ impl Body {
118118
let _p = profile::span("body_with_source_map_query");
119119
let mut params = None;
120120

121-
let (file_id, module, body, is_async_fn) = {
121+
let (file_id, body, is_async_fn) = {
122122
match def {
123123
DefWithBodyId::FunctionId(f) => {
124124
let data = db.function_data(f);
@@ -138,31 +138,29 @@ impl Body {
138138
}),
139139
)
140140
});
141-
(
142-
src.file_id,
143-
f.module(db),
144-
src.value.body().map(ast::Expr::from),
145-
data.has_async_kw(),
146-
)
141+
(src.file_id, src.value.body().map(ast::Expr::from), data.has_async_kw())
147142
}
148143
DefWithBodyId::ConstId(c) => {
149144
let c = c.lookup(db);
150145
let src = c.source(db);
151-
(src.file_id, c.module(db), src.value.body(), false)
146+
(src.file_id, src.value.body(), false)
152147
}
153148
DefWithBodyId::StaticId(s) => {
154149
let s = s.lookup(db);
155150
let src = s.source(db);
156-
(src.file_id, s.module(db), src.value.body(), false)
151+
(src.file_id, src.value.body(), false)
157152
}
158153
DefWithBodyId::VariantId(v) => {
159-
let e = v.parent.lookup(db);
160154
let src = v.parent.child_source(db);
161155
let variant = &src.value[v.local_id];
162-
(src.file_id, e.container, variant.expr(), false)
156+
(src.file_id, variant.expr(), false)
157+
}
158+
DefWithBodyId::InTypeConstId(c) => {
159+
(c.lookup(db).0.file_id, Some(c.source(db)), false)
163160
}
164161
}
165162
};
163+
let module = def.module(db);
166164
let expander = Expander::new(db, file_id, module);
167165
let (mut body, source_map) =
168166
Body::new(db, def, expander, params, body, module.krate, is_async_fn);

crates/hir-def/src/body/pretty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
4040
};
4141
format!("const {name} = ")
4242
}
43+
DefWithBodyId::InTypeConstId(_) => format!("In type const = "),
4344
DefWithBodyId::VariantId(it) => {
4445
let src = it.parent.child_source(db);
4546
let variant = &src.value[it.local_id];

crates/hir-def/src/db.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ use crate::{
2424
visibility::{self, Visibility},
2525
AnonymousConstId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId,
2626
EnumLoc, ExternBlockId, ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc,
27-
LocalEnumVariantId, LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId, MacroRulesLoc,
28-
ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId,
29-
TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId,
27+
InTypeConstId, LocalEnumVariantId, LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId,
28+
MacroRulesLoc, ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc,
29+
TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, TypeOwnerId,
30+
UnionId, UnionLoc, VariantId,
3031
};
3132

3233
#[salsa::query_group(InternDatabaseStorage)]
@@ -63,6 +64,11 @@ pub trait InternDatabase: SourceDatabase {
6364
fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId;
6465
#[salsa::interned]
6566
fn intern_anonymous_const(&self, id: (DefWithBodyId, ExprId)) -> AnonymousConstId;
67+
#[salsa::interned]
68+
fn intern_in_type_const(
69+
&self,
70+
id: (hir_expand::InFile<hir_expand::ast_id_map::FileAstId<ast::Expr>>, TypeOwnerId),
71+
) -> InTypeConstId;
6672
}
6773

6874
#[salsa::query_group(DefDatabaseStorage)]

crates/hir-def/src/expander.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl Expander {
155155
}
156156

157157
pub(crate) fn parse_path(&mut self, db: &dyn DefDatabase, path: ast::Path) -> Option<Path> {
158-
let ctx = LowerCtx::with_hygiene(db, &self.cfg_expander.hygiene);
158+
let ctx = LowerCtx::new(db, &self.cfg_expander.hygiene, self.current_file_id);
159159
Path::from_src(path, &ctx)
160160
}
161161

crates/hir-def/src/hir/type_ref.rs

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ use core::fmt;
55
use std::fmt::Write;
66

77
use hir_expand::{
8+
ast_id_map::FileAstId,
89
db::ExpandDatabase,
910
name::{AsName, Name},
10-
AstId,
11+
AstId, InFile,
1112
};
1213
use intern::Interned;
1314
use syntax::ast::{self, HasName};
@@ -118,7 +119,7 @@ pub enum TypeRef {
118119
Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability),
119120
// FIXME: for full const generics, the latter element (length) here is going to have to be an
120121
// expression that is further lowered later in hir_ty.
121-
Array(Box<TypeRef>, ConstRefOrPath),
122+
Array(Box<TypeRef>, ConstRef),
122123
Slice(Box<TypeRef>),
123124
/// A fn pointer. Last element of the vector is the return type.
124125
Fn(Vec<(Option<Name>, TypeRef)>, bool /*varargs*/, bool /*is_unsafe*/),
@@ -190,7 +191,7 @@ impl TypeRef {
190191
// `hir_def::body::lower` to lower this into an `Expr` and then evaluate it at the
191192
// `hir_ty` level, which would allow knowing the type of:
192193
// let v: [u8; 2 + 2] = [0u8; 4];
193-
let len = ConstRefOrPath::from_expr_opt(inner.expr());
194+
let len = ConstRef::from_expr_opt(ctx, inner.expr());
194195
TypeRef::Array(Box::new(TypeRef::from_ast_opt(ctx, inner.ty())), len)
195196
}
196197
ast::Type::SliceType(inner) => {
@@ -380,73 +381,84 @@ impl TypeBound {
380381
}
381382

382383
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
383-
pub enum ConstRefOrPath {
384-
Scalar(ConstRef),
384+
pub enum ConstRef {
385+
Scalar(ConcreteConstRef),
385386
Path(Name),
387+
Complex(InFile<FileAstId<ast::Expr>>),
386388
}
387389

388-
impl ConstRefOrPath {
389-
pub(crate) fn from_expr_opt(expr: Option<ast::Expr>) -> Self {
390+
impl ConstRef {
391+
pub(crate) fn from_expr_opt(lower_ctx: &LowerCtx<'_>, expr: Option<ast::Expr>) -> Self {
390392
match expr {
391-
Some(x) => Self::from_expr(x),
392-
None => Self::Scalar(ConstRef::Unknown),
393+
Some(x) => {
394+
let ast_id = lower_ctx.ast_id(&x);
395+
Self::from_expr(x, ast_id)
396+
}
397+
None => Self::Scalar(ConcreteConstRef::Unknown),
393398
}
394399
}
395400

396401
pub fn display<'a>(&'a self, db: &'a dyn ExpandDatabase) -> impl fmt::Display + 'a {
397-
struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRefOrPath);
402+
struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRef);
398403
impl fmt::Display for Display<'_> {
399404
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400405
match self.1 {
401-
ConstRefOrPath::Scalar(s) => s.fmt(f),
402-
ConstRefOrPath::Path(n) => n.display(self.0).fmt(f),
406+
ConstRef::Scalar(s) => s.fmt(f),
407+
ConstRef::Path(n) => n.display(self.0).fmt(f),
408+
ConstRef::Complex(_) => f.write_str("{const}"),
403409
}
404410
}
405411
}
406412
Display(db, self)
407413
}
408414

409-
// FIXME: as per the comments on `TypeRef::Array`, this evaluation should not happen at this
410-
// parse stage.
411-
fn from_expr(expr: ast::Expr) -> Self {
415+
// We special case literals and single identifiers, to speed up things.
416+
fn from_expr(expr: ast::Expr, ast_id: Option<InFile<FileAstId<ast::Expr>>>) -> Self {
417+
fn is_path_ident(p: &ast::PathExpr) -> bool {
418+
let Some(path) = p.path() else {
419+
return false;
420+
};
421+
if path.coloncolon_token().is_some() {
422+
return false;
423+
}
424+
if let Some(s) = path.segment() {
425+
if s.coloncolon_token().is_some() || s.generic_arg_list().is_some() {
426+
return false;
427+
}
428+
}
429+
true
430+
}
412431
match expr {
413-
ast::Expr::PathExpr(p) => {
432+
ast::Expr::PathExpr(p) if is_path_ident(&p) => {
414433
match p.path().and_then(|x| x.segment()).and_then(|x| x.name_ref()) {
415434
Some(x) => Self::Path(x.as_name()),
416-
None => Self::Scalar(ConstRef::Unknown),
435+
None => Self::Scalar(ConcreteConstRef::Unknown),
417436
}
418437
}
419-
ast::Expr::PrefixExpr(prefix_expr) => match prefix_expr.op_kind() {
420-
Some(ast::UnaryOp::Neg) => {
421-
let unsigned = Self::from_expr_opt(prefix_expr.expr());
422-
// Add sign
423-
match unsigned {
424-
Self::Scalar(ConstRef::UInt(num)) => {
425-
Self::Scalar(ConstRef::Int(-(num as i128)))
426-
}
427-
other => other,
428-
}
429-
}
430-
_ => Self::from_expr_opt(prefix_expr.expr()),
431-
},
432438
ast::Expr::Literal(literal) => Self::Scalar(match literal.kind() {
433439
ast::LiteralKind::IntNumber(num) => {
434-
num.value().map(ConstRef::UInt).unwrap_or(ConstRef::Unknown)
440+
num.value().map(ConcreteConstRef::UInt).unwrap_or(ConcreteConstRef::Unknown)
435441
}
436442
ast::LiteralKind::Char(c) => {
437-
c.value().map(ConstRef::Char).unwrap_or(ConstRef::Unknown)
443+
c.value().map(ConcreteConstRef::Char).unwrap_or(ConcreteConstRef::Unknown)
438444
}
439-
ast::LiteralKind::Bool(f) => ConstRef::Bool(f),
440-
_ => ConstRef::Unknown,
445+
ast::LiteralKind::Bool(f) => ConcreteConstRef::Bool(f),
446+
_ => ConcreteConstRef::Unknown,
441447
}),
442-
_ => Self::Scalar(ConstRef::Unknown),
448+
_ => {
449+
if let Some(ast_id) = ast_id {
450+
Self::Complex(ast_id)
451+
} else {
452+
Self::Scalar(ConcreteConstRef::Unknown)
453+
}
454+
}
443455
}
444456
}
445457
}
446458

447459
/// A concrete constant value
448460
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
449-
pub enum ConstRef {
461+
pub enum ConcreteConstRef {
450462
Int(i128),
451463
UInt(u128),
452464
Bool(bool),
@@ -460,18 +472,20 @@ pub enum ConstRef {
460472
Unknown,
461473
}
462474

463-
impl ConstRef {
475+
impl ConcreteConstRef {
464476
pub fn builtin_type(&self) -> BuiltinType {
465477
match self {
466-
ConstRef::UInt(_) | ConstRef::Unknown => BuiltinType::Uint(BuiltinUint::U128),
467-
ConstRef::Int(_) => BuiltinType::Int(BuiltinInt::I128),
468-
ConstRef::Char(_) => BuiltinType::Char,
469-
ConstRef::Bool(_) => BuiltinType::Bool,
478+
ConcreteConstRef::UInt(_) | ConcreteConstRef::Unknown => {
479+
BuiltinType::Uint(BuiltinUint::U128)
480+
}
481+
ConcreteConstRef::Int(_) => BuiltinType::Int(BuiltinInt::I128),
482+
ConcreteConstRef::Char(_) => BuiltinType::Char,
483+
ConcreteConstRef::Bool(_) => BuiltinType::Bool,
470484
}
471485
}
472486
}
473487

474-
impl From<Literal> for ConstRef {
488+
impl From<Literal> for ConcreteConstRef {
475489
fn from(literal: Literal) -> Self {
476490
match literal {
477491
Literal::Char(c) => Self::Char(c),
@@ -483,14 +497,14 @@ impl From<Literal> for ConstRef {
483497
}
484498
}
485499

486-
impl std::fmt::Display for ConstRef {
500+
impl std::fmt::Display for ConcreteConstRef {
487501
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
488502
match self {
489-
ConstRef::Int(num) => num.fmt(f),
490-
ConstRef::UInt(num) => num.fmt(f),
491-
ConstRef::Bool(flag) => flag.fmt(f),
492-
ConstRef::Char(c) => write!(f, "'{c}'"),
493-
ConstRef::Unknown => f.write_char('_'),
503+
ConcreteConstRef::Int(num) => num.fmt(f),
504+
ConcreteConstRef::UInt(num) => num.fmt(f),
505+
ConcreteConstRef::Bool(flag) => flag.fmt(f),
506+
ConcreteConstRef::Char(c) => write!(f, "'{c}'"),
507+
ConcreteConstRef::Unknown => f.write_char('_'),
494508
}
495509
}
496510
}

0 commit comments

Comments
 (0)