mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 01:17:27 +00:00
Remove ModuleId
from TypeOwnerId
This commit is contained in:
parent
070cd4e8b0
commit
9083017c9d
11 changed files with 112 additions and 45 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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}");
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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:#?}")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 => {
|
||||
|
|
Loading…
Reference in a new issue