Remove ModuleId from TypeOwnerId

This commit is contained in:
Lukas Wirth 2023-12-14 14:11:12 +01:00
parent 070cd4e8b0
commit 9083017c9d
11 changed files with 112 additions and 45 deletions

View file

@ -222,11 +222,10 @@ impl GenericParams {
let module = loc.container.module(db);
let func_data = db.function_data(id);
// Don't create an `Expander` nor call `loc.source(db)` if not needed since this
// causes a reparse after the `ItemTree` has been created.
let mut expander = Lazy::new(|| {
(module.def_map(db), Expander::new(db, loc.source(db).file_id, module))
});
// Don't create an `Expander` if not needed since this
// could cause a reparse after the `ItemTree` has been created due to the spanmap.
let mut expander =
Lazy::new(|| (module.def_map(db), Expander::new(db, loc.id.file_id(), module)));
for param in func_data.params.iter() {
generic_params.fill_implicit_impl_trait_args(db, &mut expander, param);
}

View file

@ -106,11 +106,6 @@ impl ItemTree {
pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
let _p = profile::span("file_item_tree_query").detail(|| format!("{file_id:?}"));
let syntax = db.parse_or_expand(file_id);
if never!(syntax.kind() == SyntaxKind::ERROR, "{:?} from {:?} {}", file_id, syntax, syntax)
{
// FIXME: not 100% sure why these crop up, but return an empty tree to avoid a panic
return Default::default();
}
let ctx = lower::Ctx::new(db, file_id);
let mut top_attrs = None;
@ -129,6 +124,9 @@ impl ItemTree {
ctx.lower_macro_stmts(stmts)
},
_ => {
if never!(syntax.kind() == SyntaxKind::ERROR, "{:?} from {:?} {}", file_id, syntax, syntax) {
return Default::default();
}
panic!("cannot create item tree for file {file_id:?} from {syntax:?} {syntax}");
},
}

View file

@ -569,6 +569,8 @@ pub struct ConstBlockLoc {
pub root: hir::ExprId,
}
/// Something that holds types, required for the current const arg lowering implementation as they
/// need to be able to query where they are defined.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum TypeOwnerId {
FunctionId(FunctionId),
@ -581,9 +583,6 @@ pub enum TypeOwnerId {
TypeAliasId(TypeAliasId),
ImplId(ImplId),
EnumVariantId(EnumVariantId),
// FIXME(const-generic-body): ModuleId should not be a type owner. This needs to be fixed to make `TypeOwnerId` actually
// useful for assigning ids to in type consts.
ModuleId(ModuleId),
}
impl TypeOwnerId {
@ -597,9 +596,7 @@ impl TypeOwnerId {
TypeOwnerId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
TypeOwnerId::ImplId(it) => GenericDefId::ImplId(it),
TypeOwnerId::EnumVariantId(it) => GenericDefId::EnumVariantId(it),
TypeOwnerId::InTypeConstId(_) | TypeOwnerId::ModuleId(_) | TypeOwnerId::StaticId(_) => {
return None
}
TypeOwnerId::InTypeConstId(_) | TypeOwnerId::StaticId(_) => return None,
})
}
}
@ -614,8 +611,7 @@ impl_from!(
TraitAliasId,
TypeAliasId,
ImplId,
EnumVariantId,
ModuleId
EnumVariantId
for TypeOwnerId
);
@ -713,12 +709,15 @@ pub struct InTypeConstLoc {
pub id: AstId<ast::ConstArg>,
/// The thing this const arg appears in
pub owner: TypeOwnerId,
pub thing: Box<dyn OpaqueInternableThing>,
// FIXME(const-generic-body): The expected type should not be
pub expected_ty: Box<dyn OpaqueInternableThing>,
}
impl PartialEq for InTypeConstLoc {
fn eq(&self, other: &Self) -> bool {
self.id == other.id && self.owner == other.owner && &*self.thing == &*other.thing
self.id == other.id
&& self.owner == other.owner
&& &*self.expected_ty == &*other.expected_ty
}
}
@ -1041,7 +1040,6 @@ impl HasModule for TypeOwnerId {
TypeOwnerId::TypeAliasId(it) => it.lookup(db).module(db),
TypeOwnerId::ImplId(it) => it.lookup(db).container,
TypeOwnerId::EnumVariantId(it) => it.parent.lookup(db).container,
TypeOwnerId::ModuleId(it) => *it,
}
}
}

View file

@ -589,6 +589,16 @@ impl Resolver {
})
}
pub fn type_owner(&self) -> Option<TypeOwnerId> {
self.scopes().find_map(|scope| match scope {
Scope::BlockScope(_) => None,
&Scope::GenericParams { def, .. } => Some(def.into()),
&Scope::ImplDefScope(id) => Some(id.into()),
&Scope::AdtScope(adt) => Some(adt.into()),
Scope::ExprScope(it) => Some(it.owner.into()),
})
}
pub fn impl_def(&self) -> Option<ImplId> {
self.scopes().find_map(|scope| match scope {
Scope::ImplDefScope(def) => Some(*def),
@ -1079,7 +1089,6 @@ impl HasResolver for TypeOwnerId {
TypeOwnerId::TypeAliasId(it) => it.resolver(db),
TypeOwnerId::ImplId(it) => it.resolver(db),
TypeOwnerId::EnumVariantId(it) => it.resolver(db),
TypeOwnerId::ModuleId(it) => it.resolver(db),
}
}
}

View file

@ -88,7 +88,7 @@ pub fn expand_eager_macro_input(
let loc = MacroCallLoc {
def,
krate,
eager: Some(Box::new(EagerCallInfo { arg: Arc::new(subtree), arg_id, error: err.clone() })),
eager: Some(Arc::new(EagerCallInfo { arg: Arc::new(subtree), arg_id, error: err.clone() })),
kind: MacroCallKind::FnLike { ast_id: call_id, expand_to },
call_site,
};

View file

@ -117,7 +117,7 @@ pub struct MacroCallLoc {
pub krate: CrateId,
/// Some if this is a macro call for an eager macro. Note that this is `None`
/// for the eager input macro file.
eager: Option<Box<EagerCallInfo>>,
eager: Option<Arc<EagerCallInfo>>,
pub kind: MacroCallKind,
pub call_site: SyntaxContextId,
}

View file

@ -113,7 +113,7 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
// FIXME(const-generic-body): We should not get the return type in this way.
ctx.return_ty = c
.lookup(db.upcast())
.thing
.expected_ty
.box_any()
.downcast::<InTypeConstIdMetadata>()
.unwrap()

View file

@ -113,7 +113,9 @@ pub struct TyLoweringContext<'a> {
pub db: &'a dyn HirDatabase,
resolver: &'a Resolver,
in_binders: DebruijnIndex,
owner: TypeOwnerId,
// FIXME: Should not be an `Option` but `Resolver` currently does not return owners in all cases
// where expected
owner: Option<TypeOwnerId>,
/// Note: Conceptually, it's thinkable that we could be in a location where
/// some type params should be represented as placeholders, and others
/// should be converted to variables. I think in practice, this isn't
@ -127,6 +129,14 @@ pub struct TyLoweringContext<'a> {
impl<'a> TyLoweringContext<'a> {
pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver, owner: TypeOwnerId) -> Self {
Self::new_maybe_unowned(db, resolver, Some(owner))
}
pub fn new_maybe_unowned(
db: &'a dyn HirDatabase,
resolver: &'a Resolver,
owner: Option<TypeOwnerId>,
) -> Self {
let impl_trait_mode = ImplTraitLoweringState::Disallowed;
let type_param_mode = ParamLoweringMode::Placeholder;
let in_binders = DebruijnIndex::INNERMOST;
@ -213,10 +223,11 @@ impl<'a> TyLoweringContext<'a> {
}
pub fn lower_const(&self, const_ref: &ConstRef, const_type: Ty) -> Const {
let Some(owner) = self.owner else { return unknown_const(const_type) };
const_or_path_to_chalk(
self.db,
self.resolver,
self.owner,
owner,
const_type,
const_ref,
self.type_param_mode,
@ -1768,10 +1779,11 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
let resolver = t.resolver(db.upcast());
let ctx = TyLoweringContext::new(db, &resolver, t.into())
.with_type_param_mode(ParamLoweringMode::Variable);
if db.type_alias_data(t).is_extern {
let type_alias_data = db.type_alias_data(t);
if type_alias_data.is_extern {
Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
} else {
let type_ref = &db.type_alias_data(t).type_ref;
let type_ref = &type_alias_data.type_ref;
let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
make_binders(db, &generics, inner)
}
@ -2042,7 +2054,7 @@ pub(crate) fn const_or_path_to_chalk(
.intern_in_type_const(InTypeConstLoc {
id: it,
owner,
thing: Box::new(InTypeConstIdMetadata(expected_ty.clone())),
expected_ty: Box::new(InTypeConstIdMetadata(expected_ty.clone())),
})
.into();
intern_const_scalar(

View file

@ -9,11 +9,10 @@ use super::visit_module;
fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
let (mut db, pos) = TestDB::with_position(
"
//- /lib.rs
fn foo() -> i32 {
$01 + 1
}
",
//- /lib.rs
fn foo() -> i32 {
$01 + 1
}",
);
{
let events = db.log_executed(|| {
@ -27,12 +26,11 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
}
let new_text = "
fn foo() -> i32 {
1
+
1
}
";
fn foo() -> i32 {
1
+
1
}";
db.set_file_text(pos.file_id, Arc::from(new_text));
@ -47,3 +45,55 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
assert!(!format!("{events:?}").contains("infer"), "{events:#?}")
}
}
#[test]
fn typing_inside_a_function_should_not_invalidate_types_in_another() {
let (mut db, pos) = TestDB::with_position(
"
//- /lib.rs
fn foo() -> f32 {
1.0 + 2.0
}
fn bar() -> i32 {
$01 + 1
}
fn baz() -> i32 {
1 + 1
}",
);
{
let events = db.log_executed(|| {
let module = db.module_for_file(pos.file_id);
let crate_def_map = module.def_map(&db);
visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
db.infer(def);
});
});
assert!(format!("{events:?}").contains("infer"))
}
let new_text = "
fn foo() -> f32 {
1.0 + 2.0
}
fn bar() -> i32 {
53
}
fn baz() -> i32 {
1 + 1
}
";
db.set_file_text(pos.file_id, Arc::from(new_text));
{
let events = db.log_executed(|| {
let module = db.module_for_file(pos.file_id);
let crate_def_map = module.def_map(&db);
visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
db.infer(def);
});
});
assert!(format!("{events:?}").matches("infer").count() == 1, "{events:#?}")
}
}

View file

@ -948,10 +948,10 @@ impl<'db> SemanticsImpl<'db> {
pub fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
let analyze = self.analyze(ty.syntax())?;
let ctx = LowerCtx::with_file_id(self.db.upcast(), analyze.file_id);
let ty = hir_ty::TyLoweringContext::new(
let ty = hir_ty::TyLoweringContext::new_maybe_unowned(
self.db,
&analyze.resolver,
analyze.resolver.module().into(),
analyze.resolver.type_owner(),
)
.lower_ty(&crate::TypeRef::from_ast(&ctx, ty.clone()));
Some(Type::new_with_resolver(self.db, &analyze.resolver, ty))

View file

@ -1040,8 +1040,9 @@ fn resolve_hir_path_(
let types = || {
let (ty, unresolved) = match path.type_anchor() {
Some(type_ref) => {
let (_, res) = TyLoweringContext::new(db, resolver, resolver.module().into())
.lower_ty_ext(type_ref);
let (_, res) =
TyLoweringContext::new_maybe_unowned(db, resolver, resolver.type_owner())
.lower_ty_ext(type_ref);
res.map(|ty_ns| (ty_ns, path.segments().first()))
}
None => {