Auto merge of #16123 - Veykril:simplify, r=Veykril

internal: Remove `ModuleId` from `TypeOwnerId`

It only exists due to the IDE layer, but we can encode this temporary hack more cleanly
This commit is contained in:
bors 2023-12-15 13:10:17 +00:00
commit a7764198b1
11 changed files with 112 additions and 45 deletions

View file

@ -222,11 +222,10 @@ impl GenericParams {
let module = loc.container.module(db); let module = loc.container.module(db);
let func_data = db.function_data(id); let func_data = db.function_data(id);
// Don't create an `Expander` nor call `loc.source(db)` if not needed since this // Don't create an `Expander` if not needed since this
// causes a reparse after the `ItemTree` has been created. // could cause a reparse after the `ItemTree` has been created due to the spanmap.
let mut expander = Lazy::new(|| { let mut expander =
(module.def_map(db), Expander::new(db, loc.source(db).file_id, module)) Lazy::new(|| (module.def_map(db), Expander::new(db, loc.id.file_id(), module)));
});
for param in func_data.params.iter() { for param in func_data.params.iter() {
generic_params.fill_implicit_impl_trait_args(db, &mut expander, param); 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> { 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 _p = profile::span("file_item_tree_query").detail(|| format!("{file_id:?}"));
let syntax = db.parse_or_expand(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 ctx = lower::Ctx::new(db, file_id);
let mut top_attrs = None; let mut top_attrs = None;
@ -129,6 +124,9 @@ impl ItemTree {
ctx.lower_macro_stmts(stmts) 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}"); 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, 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)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum TypeOwnerId { pub enum TypeOwnerId {
FunctionId(FunctionId), FunctionId(FunctionId),
@ -581,9 +583,6 @@ pub enum TypeOwnerId {
TypeAliasId(TypeAliasId), TypeAliasId(TypeAliasId),
ImplId(ImplId), ImplId(ImplId),
EnumVariantId(EnumVariantId), 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 { impl TypeOwnerId {
@ -597,9 +596,7 @@ impl TypeOwnerId {
TypeOwnerId::TypeAliasId(it) => GenericDefId::TypeAliasId(it), TypeOwnerId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
TypeOwnerId::ImplId(it) => GenericDefId::ImplId(it), TypeOwnerId::ImplId(it) => GenericDefId::ImplId(it),
TypeOwnerId::EnumVariantId(it) => GenericDefId::EnumVariantId(it), TypeOwnerId::EnumVariantId(it) => GenericDefId::EnumVariantId(it),
TypeOwnerId::InTypeConstId(_) | TypeOwnerId::ModuleId(_) | TypeOwnerId::StaticId(_) => { TypeOwnerId::InTypeConstId(_) | TypeOwnerId::StaticId(_) => return None,
return None
}
}) })
} }
} }
@ -614,8 +611,7 @@ impl_from!(
TraitAliasId, TraitAliasId,
TypeAliasId, TypeAliasId,
ImplId, ImplId,
EnumVariantId, EnumVariantId
ModuleId
for TypeOwnerId for TypeOwnerId
); );
@ -713,12 +709,15 @@ pub struct InTypeConstLoc {
pub id: AstId<ast::ConstArg>, pub id: AstId<ast::ConstArg>,
/// The thing this const arg appears in /// The thing this const arg appears in
pub owner: TypeOwnerId, 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 { impl PartialEq for InTypeConstLoc {
fn eq(&self, other: &Self) -> bool { 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::TypeAliasId(it) => it.lookup(db).module(db),
TypeOwnerId::ImplId(it) => it.lookup(db).container, TypeOwnerId::ImplId(it) => it.lookup(db).container,
TypeOwnerId::EnumVariantId(it) => it.parent.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> { pub fn impl_def(&self) -> Option<ImplId> {
self.scopes().find_map(|scope| match scope { self.scopes().find_map(|scope| match scope {
Scope::ImplDefScope(def) => Some(*def), Scope::ImplDefScope(def) => Some(*def),
@ -1079,7 +1089,6 @@ impl HasResolver for TypeOwnerId {
TypeOwnerId::TypeAliasId(it) => it.resolver(db), TypeOwnerId::TypeAliasId(it) => it.resolver(db),
TypeOwnerId::ImplId(it) => it.resolver(db), TypeOwnerId::ImplId(it) => it.resolver(db),
TypeOwnerId::EnumVariantId(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 { let loc = MacroCallLoc {
def, def,
krate, 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 }, kind: MacroCallKind::FnLike { ast_id: call_id, expand_to },
call_site, call_site,
}; };

View file

@ -117,7 +117,7 @@ pub struct MacroCallLoc {
pub krate: CrateId, pub krate: CrateId,
/// Some if this is a macro call for an eager macro. Note that this is `None` /// Some if this is a macro call for an eager macro. Note that this is `None`
/// for the eager input macro file. /// for the eager input macro file.
eager: Option<Box<EagerCallInfo>>, eager: Option<Arc<EagerCallInfo>>,
pub kind: MacroCallKind, pub kind: MacroCallKind,
pub call_site: SyntaxContextId, 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. // FIXME(const-generic-body): We should not get the return type in this way.
ctx.return_ty = c ctx.return_ty = c
.lookup(db.upcast()) .lookup(db.upcast())
.thing .expected_ty
.box_any() .box_any()
.downcast::<InTypeConstIdMetadata>() .downcast::<InTypeConstIdMetadata>()
.unwrap() .unwrap()

View file

@ -113,7 +113,9 @@ pub struct TyLoweringContext<'a> {
pub db: &'a dyn HirDatabase, pub db: &'a dyn HirDatabase,
resolver: &'a Resolver, resolver: &'a Resolver,
in_binders: DebruijnIndex, 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 /// Note: Conceptually, it's thinkable that we could be in a location where
/// some type params should be represented as placeholders, and others /// some type params should be represented as placeholders, and others
/// should be converted to variables. I think in practice, this isn't /// should be converted to variables. I think in practice, this isn't
@ -127,6 +129,14 @@ pub struct TyLoweringContext<'a> {
impl<'a> TyLoweringContext<'a> { impl<'a> TyLoweringContext<'a> {
pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver, owner: TypeOwnerId) -> Self { 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 impl_trait_mode = ImplTraitLoweringState::Disallowed;
let type_param_mode = ParamLoweringMode::Placeholder; let type_param_mode = ParamLoweringMode::Placeholder;
let in_binders = DebruijnIndex::INNERMOST; 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 { 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( const_or_path_to_chalk(
self.db, self.db,
self.resolver, self.resolver,
self.owner, owner,
const_type, const_type,
const_ref, const_ref,
self.type_param_mode, 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 resolver = t.resolver(db.upcast());
let ctx = TyLoweringContext::new(db, &resolver, t.into()) let ctx = TyLoweringContext::new(db, &resolver, t.into())
.with_type_param_mode(ParamLoweringMode::Variable); .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)) Binders::empty(Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner))
} else { } 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)); let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
make_binders(db, &generics, inner) make_binders(db, &generics, inner)
} }
@ -2042,7 +2054,7 @@ pub(crate) fn const_or_path_to_chalk(
.intern_in_type_const(InTypeConstLoc { .intern_in_type_const(InTypeConstLoc {
id: it, id: it,
owner, owner,
thing: Box::new(InTypeConstIdMetadata(expected_ty.clone())), expected_ty: Box::new(InTypeConstIdMetadata(expected_ty.clone())),
}) })
.into(); .into();
intern_const_scalar( intern_const_scalar(

View file

@ -9,11 +9,10 @@ use super::visit_module;
fn typing_whitespace_inside_a_function_should_not_invalidate_types() { fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
let (mut db, pos) = TestDB::with_position( let (mut db, pos) = TestDB::with_position(
" "
//- /lib.rs //- /lib.rs
fn foo() -> i32 { fn foo() -> i32 {
$01 + 1 $01 + 1
} }",
",
); );
{ {
let events = db.log_executed(|| { let events = db.log_executed(|| {
@ -27,12 +26,11 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
} }
let new_text = " let new_text = "
fn foo() -> i32 { fn foo() -> i32 {
1 1
+ +
1 1
} }";
";
db.set_file_text(pos.file_id, Arc::from(new_text)); 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:#?}") 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> { pub fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
let analyze = self.analyze(ty.syntax())?; let analyze = self.analyze(ty.syntax())?;
let ctx = LowerCtx::with_file_id(self.db.upcast(), analyze.file_id); 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, self.db,
&analyze.resolver, &analyze.resolver,
analyze.resolver.module().into(), analyze.resolver.type_owner(),
) )
.lower_ty(&crate::TypeRef::from_ast(&ctx, ty.clone())); .lower_ty(&crate::TypeRef::from_ast(&ctx, ty.clone()));
Some(Type::new_with_resolver(self.db, &analyze.resolver, ty)) Some(Type::new_with_resolver(self.db, &analyze.resolver, ty))

View file

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