mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 20:09:19 +00:00
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:
commit
a7764198b1
11 changed files with 112 additions and 45 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}");
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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:#?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue