Skip to content

Commit a481e00

Browse files
committed
Lower const params with a bad id
1 parent 68bdf60 commit a481e00

File tree

38 files changed

+473
-182
lines changed

38 files changed

+473
-182
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: 21 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,
@@ -456,6 +473,10 @@ impl CrateGraph {
456473
self.arena.iter().map(|(idx, _)| idx)
457474
}
458475

476+
pub fn iter_mut(&mut self) -> impl Iterator<Item = (CrateId, &mut CrateData)> + '_ {
477+
self.arena.iter_mut()
478+
}
479+
459480
/// Returns an iterator over all transitive dependencies of the given crate,
460481
/// including the crate itself.
461482
pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = 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: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Defines database & queries for name resolution.
22
use base_db::{salsa, CrateId, SourceDatabase, Upcast};
33
use either::Either;
4-
use hir_expand::{db::ExpandDatabase, HirFileId};
4+
use hir_expand::{db::ExpandDatabase, AstId, HirFileId};
55
use intern::Interned;
66
use la_arena::ArenaMap;
77
use syntax::{ast, AstPtr};
@@ -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,8 @@ 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(&self, id: (AstId<ast::Expr>, TypeOwnerId)) -> InTypeConstId;
6669
}
6770

6871
#[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: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pub enum TypeRef {
118118
Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability),
119119
// FIXME: for full const generics, the latter element (length) here is going to have to be an
120120
// expression that is further lowered later in hir_ty.
121-
Array(Box<TypeRef>, ConstRefOrPath),
121+
Array(Box<TypeRef>, ConstRef),
122122
Slice(Box<TypeRef>),
123123
/// A fn pointer. Last element of the vector is the return type.
124124
Fn(Vec<(Option<Name>, TypeRef)>, bool /*varargs*/, bool /*is_unsafe*/),
@@ -190,7 +190,7 @@ impl TypeRef {
190190
// `hir_def::body::lower` to lower this into an `Expr` and then evaluate it at the
191191
// `hir_ty` level, which would allow knowing the type of:
192192
// let v: [u8; 2 + 2] = [0u8; 4];
193-
let len = ConstRefOrPath::from_expr_opt(inner.expr());
193+
let len = ConstRef::from_expr_opt(ctx, inner.expr());
194194
TypeRef::Array(Box::new(TypeRef::from_ast_opt(ctx, inner.ty())), len)
195195
}
196196
ast::Type::SliceType(inner) => {
@@ -380,73 +380,84 @@ impl TypeBound {
380380
}
381381

382382
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
383-
pub enum ConstRefOrPath {
384-
Scalar(ConstRef),
383+
pub enum ConstRef {
384+
Scalar(LiteralConstRef),
385385
Path(Name),
386+
Complex(AstId<ast::Expr>),
386387
}
387388

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

396400
pub fn display<'a>(&'a self, db: &'a dyn ExpandDatabase) -> impl fmt::Display + 'a {
397-
struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRefOrPath);
401+
struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRef);
398402
impl fmt::Display for Display<'_> {
399403
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400404
match self.1 {
401-
ConstRefOrPath::Scalar(s) => s.fmt(f),
402-
ConstRefOrPath::Path(n) => n.display(self.0).fmt(f),
405+
ConstRef::Scalar(s) => s.fmt(f),
406+
ConstRef::Path(n) => n.display(self.0).fmt(f),
407+
ConstRef::Complex(_) => f.write_str("{const}"),
403408
}
404409
}
405410
}
406411
Display(db, self)
407412
}
408413

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 {
414+
// We special case literals and single identifiers, to speed up things.
415+
fn from_expr(expr: ast::Expr, ast_id: Option<AstId<ast::Expr>>) -> Self {
416+
fn is_path_ident(p: &ast::PathExpr) -> bool {
417+
let Some(path) = p.path() else {
418+
return false;
419+
};
420+
if path.coloncolon_token().is_some() {
421+
return false;
422+
}
423+
if let Some(s) = path.segment() {
424+
if s.coloncolon_token().is_some() || s.generic_arg_list().is_some() {
425+
return false;
426+
}
427+
}
428+
true
429+
}
412430
match expr {
413-
ast::Expr::PathExpr(p) => {
431+
ast::Expr::PathExpr(p) if is_path_ident(&p) => {
414432
match p.path().and_then(|x| x.segment()).and_then(|x| x.name_ref()) {
415433
Some(x) => Self::Path(x.as_name()),
416-
None => Self::Scalar(ConstRef::Unknown),
434+
None => Self::Scalar(LiteralConstRef::Unknown),
417435
}
418436
}
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-
},
432437
ast::Expr::Literal(literal) => Self::Scalar(match literal.kind() {
433438
ast::LiteralKind::IntNumber(num) => {
434-
num.value().map(ConstRef::UInt).unwrap_or(ConstRef::Unknown)
439+
num.value().map(LiteralConstRef::UInt).unwrap_or(LiteralConstRef::Unknown)
435440
}
436441
ast::LiteralKind::Char(c) => {
437-
c.value().map(ConstRef::Char).unwrap_or(ConstRef::Unknown)
442+
c.value().map(LiteralConstRef::Char).unwrap_or(LiteralConstRef::Unknown)
438443
}
439-
ast::LiteralKind::Bool(f) => ConstRef::Bool(f),
440-
_ => ConstRef::Unknown,
444+
ast::LiteralKind::Bool(f) => LiteralConstRef::Bool(f),
445+
_ => LiteralConstRef::Unknown,
441446
}),
442-
_ => Self::Scalar(ConstRef::Unknown),
447+
_ => {
448+
if let Some(ast_id) = ast_id {
449+
Self::Complex(ast_id)
450+
} else {
451+
Self::Scalar(LiteralConstRef::Unknown)
452+
}
453+
}
443454
}
444455
}
445456
}
446457

447-
/// A concrete constant value
458+
/// A literal constant value
448459
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
449-
pub enum ConstRef {
460+
pub enum LiteralConstRef {
450461
Int(i128),
451462
UInt(u128),
452463
Bool(bool),
@@ -460,18 +471,20 @@ pub enum ConstRef {
460471
Unknown,
461472
}
462473

463-
impl ConstRef {
474+
impl LiteralConstRef {
464475
pub fn builtin_type(&self) -> BuiltinType {
465476
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,
477+
LiteralConstRef::UInt(_) | LiteralConstRef::Unknown => {
478+
BuiltinType::Uint(BuiltinUint::U128)
479+
}
480+
LiteralConstRef::Int(_) => BuiltinType::Int(BuiltinInt::I128),
481+
LiteralConstRef::Char(_) => BuiltinType::Char,
482+
LiteralConstRef::Bool(_) => BuiltinType::Bool,
470483
}
471484
}
472485
}
473486

474-
impl From<Literal> for ConstRef {
487+
impl From<Literal> for LiteralConstRef {
475488
fn from(literal: Literal) -> Self {
476489
match literal {
477490
Literal::Char(c) => Self::Char(c),
@@ -483,14 +496,14 @@ impl From<Literal> for ConstRef {
483496
}
484497
}
485498

486-
impl std::fmt::Display for ConstRef {
499+
impl std::fmt::Display for LiteralConstRef {
487500
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
488501
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('_'),
502+
LiteralConstRef::Int(num) => num.fmt(f),
503+
LiteralConstRef::UInt(num) => num.fmt(f),
504+
LiteralConstRef::Bool(flag) => flag.fmt(f),
505+
LiteralConstRef::Char(c) => write!(f, "'{c}'"),
506+
LiteralConstRef::Unknown => f.write_char('_'),
494507
}
495508
}
496509
}

0 commit comments

Comments
 (0)