Restore to main
This commit is contained in:
@@ -150,7 +150,7 @@ macro_rules! impl_binding_has_ty {
|
||||
fn ty<'db>(&self, model: &SemanticModel<'db>) -> Type<'db> {
|
||||
let index = semantic_index(model.db, model.file);
|
||||
let binding = index.definition(self);
|
||||
binding_ty(model.db, binding, false)
|
||||
binding_ty(model.db, binding)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -70,7 +70,7 @@ fn symbol_by_id<'db>(db: &'db dyn Db, scope: ScopeId<'db>, symbol: ScopedSymbolI
|
||||
// If the symbol is undeclared in some paths, include the inferred type in the public type.
|
||||
let undeclared_ty = if declarations.may_be_undeclared() {
|
||||
Some(
|
||||
bindings_ty(db, use_def.public_bindings(symbol), false)
|
||||
bindings_ty(db, use_def.public_bindings(symbol))
|
||||
.map(|bindings_ty| Symbol::Type(bindings_ty, use_def.public_boundness(symbol)))
|
||||
.unwrap_or(Symbol::Unbound),
|
||||
)
|
||||
@@ -106,7 +106,7 @@ fn symbol_by_id<'db>(db: &'db dyn Db, scope: ScopeId<'db>, symbol: ScopedSymbolI
|
||||
),
|
||||
}
|
||||
} else {
|
||||
bindings_ty(db, use_def.public_bindings(symbol), false)
|
||||
bindings_ty(db, use_def.public_bindings(symbol))
|
||||
.map(|bindings_ty| Symbol::Type(bindings_ty, use_def.public_boundness(symbol)))
|
||||
.unwrap_or(Symbol::Unbound)
|
||||
}
|
||||
@@ -181,18 +181,14 @@ pub(crate) fn global_symbol<'db>(db: &'db dyn Db, file: File, name: &str) -> Sym
|
||||
}
|
||||
|
||||
/// Infer the type of a binding.
|
||||
pub(crate) fn binding_ty<'db>(
|
||||
db: &'db dyn Db,
|
||||
definition: Definition<'db>,
|
||||
is_unreachable: bool,
|
||||
) -> Type<'db> {
|
||||
let inference = infer_definition_types(db, definition, is_unreachable);
|
||||
pub(crate) fn binding_ty<'db>(db: &'db dyn Db, definition: Definition<'db>) -> Type<'db> {
|
||||
let inference = infer_definition_types(db, definition);
|
||||
inference.binding_ty(definition)
|
||||
}
|
||||
|
||||
/// Infer the type of a declaration.
|
||||
fn declaration_ty<'db>(db: &'db dyn Db, definition: Definition<'db>) -> Type<'db> {
|
||||
let inference = infer_definition_types(db, definition, false);
|
||||
let inference = infer_definition_types(db, definition);
|
||||
inference.declaration_ty(definition)
|
||||
}
|
||||
|
||||
@@ -214,7 +210,7 @@ fn definition_expression_ty<'db>(
|
||||
let expr_id = expression.scoped_expression_id(db, scope);
|
||||
if scope == definition.scope(db) {
|
||||
// expression is in the definition scope
|
||||
let inference = infer_definition_types(db, definition, false);
|
||||
let inference = infer_definition_types(db, definition);
|
||||
if let Some(ty) = inference.try_expression_ty(expr_id) {
|
||||
ty
|
||||
} else {
|
||||
@@ -232,7 +228,6 @@ fn definition_expression_ty<'db>(
|
||||
fn bindings_ty<'db>(
|
||||
db: &'db dyn Db,
|
||||
bindings_with_constraints: BindingWithConstraintsIterator<'_, 'db>,
|
||||
is_unreachable: bool,
|
||||
) -> Option<Type<'db>> {
|
||||
let mut def_types = bindings_with_constraints.map(
|
||||
|BindingWithConstraints {
|
||||
@@ -243,7 +238,7 @@ fn bindings_ty<'db>(
|
||||
.filter_map(|constraint| narrowing_constraint(db, constraint, binding))
|
||||
.peekable();
|
||||
|
||||
let binding_ty = binding_ty(db, binding, is_unreachable);
|
||||
let binding_ty = binding_ty(db, binding);
|
||||
if constraint_tys.peek().is_some() {
|
||||
constraint_tys
|
||||
.fold(
|
||||
|
||||
@@ -79,7 +79,7 @@ pub(crate) fn infer_scope_types<'db>(db: &'db dyn Db, scope: ScopeId<'db>) -> Ty
|
||||
// The isolation of the query is by the return inferred types.
|
||||
let index = semantic_index(db, file);
|
||||
|
||||
TypeInferenceBuilder::new(db, InferenceRegion::Scope(scope), index, false).finish()
|
||||
TypeInferenceBuilder::new(db, InferenceRegion::Scope(scope), index).finish()
|
||||
}
|
||||
|
||||
/// Cycle recovery for [`infer_definition_types()`]: for now, just [`Type::Unknown`]
|
||||
@@ -88,7 +88,6 @@ fn infer_definition_types_cycle_recovery<'db>(
|
||||
db: &'db dyn Db,
|
||||
_cycle: &salsa::Cycle,
|
||||
input: Definition<'db>,
|
||||
_is_unreachable: bool,
|
||||
) -> TypeInference<'db> {
|
||||
tracing::trace!("infer_definition_types_cycle_recovery");
|
||||
let mut inference = TypeInference::empty(input.scope(db));
|
||||
@@ -110,7 +109,6 @@ fn infer_definition_types_cycle_recovery<'db>(
|
||||
pub(crate) fn infer_definition_types<'db>(
|
||||
db: &'db dyn Db,
|
||||
definition: Definition<'db>,
|
||||
is_unreachable: bool,
|
||||
) -> TypeInference<'db> {
|
||||
let file = definition.file(db);
|
||||
let _span = tracing::trace_span!(
|
||||
@@ -122,13 +120,7 @@ pub(crate) fn infer_definition_types<'db>(
|
||||
|
||||
let index = semantic_index(db, file);
|
||||
|
||||
TypeInferenceBuilder::new(
|
||||
db,
|
||||
InferenceRegion::Definition(definition),
|
||||
index,
|
||||
is_unreachable,
|
||||
)
|
||||
.finish()
|
||||
TypeInferenceBuilder::new(db, InferenceRegion::Definition(definition), index).finish()
|
||||
}
|
||||
|
||||
/// Infer types for all deferred type expressions in a [`Definition`].
|
||||
@@ -150,7 +142,7 @@ pub(crate) fn infer_deferred_types<'db>(
|
||||
|
||||
let index = semantic_index(db, file);
|
||||
|
||||
TypeInferenceBuilder::new(db, InferenceRegion::Deferred(definition), index, false).finish()
|
||||
TypeInferenceBuilder::new(db, InferenceRegion::Deferred(definition), index).finish()
|
||||
}
|
||||
|
||||
/// Infer all types for an [`Expression`] (including sub-expressions).
|
||||
@@ -170,7 +162,7 @@ pub(crate) fn infer_expression_types<'db>(
|
||||
|
||||
let index = semantic_index(db, file);
|
||||
|
||||
TypeInferenceBuilder::new(db, InferenceRegion::Expression(expression), index, false).finish()
|
||||
TypeInferenceBuilder::new(db, InferenceRegion::Expression(expression), index).finish()
|
||||
}
|
||||
|
||||
/// Infer the types for an [`Unpack`] operation.
|
||||
@@ -350,8 +342,6 @@ pub(super) struct TypeInferenceBuilder<'db> {
|
||||
/// is a stub file but we're still in a non-deferred region.
|
||||
deferred_state: DeferredExpressionState,
|
||||
|
||||
is_unreachable: bool,
|
||||
|
||||
diagnostics: TypeCheckDiagnosticsBuilder<'db>,
|
||||
}
|
||||
|
||||
@@ -367,7 +357,6 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
db: &'db dyn Db,
|
||||
region: InferenceRegion<'db>,
|
||||
index: &'db SemanticIndex<'db>,
|
||||
is_unreachable: bool,
|
||||
) -> Self {
|
||||
let (file, scope) = match region {
|
||||
InferenceRegion::Expression(expression) => (expression.file(db), expression.scope(db)),
|
||||
@@ -383,7 +372,6 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
region,
|
||||
file,
|
||||
deferred_state: DeferredExpressionState::None,
|
||||
is_unreachable,
|
||||
types: TypeInference::empty(scope),
|
||||
diagnostics: TypeCheckDiagnosticsBuilder::new(db, file),
|
||||
}
|
||||
@@ -396,14 +384,6 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
self.types
|
||||
.declarations
|
||||
.extend(inference.declarations.iter());
|
||||
// dbg!("Merging:");
|
||||
// dbg!(&inference.expressions);
|
||||
// dbg!("Into:");
|
||||
// dbg!(&self.types.expressions);
|
||||
debug_assert!(inference
|
||||
.expressions
|
||||
.keys()
|
||||
.all(|id| { self.types.expressions.get(id).is_none() }));
|
||||
self.types.expressions.extend(inference.expressions.iter());
|
||||
self.types.deferred.extend(inference.deferred.iter());
|
||||
self.diagnostics.extend(&inference.diagnostics);
|
||||
@@ -803,7 +783,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
let use_def = self.index.use_def_map(declaration.file_scope(self.db));
|
||||
let prior_bindings = use_def.bindings_at_declaration(declaration);
|
||||
// unbound_ty is Never because for this check we don't care about unbound
|
||||
let inferred_ty = bindings_ty(self.db, prior_bindings, false).unwrap_or(Type::Never);
|
||||
let inferred_ty = bindings_ty(self.db, prior_bindings).unwrap_or(Type::Never);
|
||||
let ty = if inferred_ty.is_assignable_to(self.db, ty) {
|
||||
ty
|
||||
} else {
|
||||
@@ -938,8 +918,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
|
||||
fn infer_definition(&mut self, node: impl Into<DefinitionNodeKey>) {
|
||||
let definition = self.index.definition(node);
|
||||
let result = infer_definition_types(self.db, definition, self.is_unreachable);
|
||||
dbg!(result);
|
||||
let result = infer_definition_types(self.db, definition);
|
||||
self.extend(result);
|
||||
}
|
||||
|
||||
@@ -1186,16 +1165,8 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
elif_else_clauses,
|
||||
} = if_statement;
|
||||
|
||||
let test_ty = self.infer_standalone_expression(test);
|
||||
|
||||
let body_is_unreachable = test_ty.bool(self.db) == Truthiness::AlwaysFalse;
|
||||
|
||||
if body_is_unreachable {
|
||||
dbg!("Body is unreachable");
|
||||
self.is_unreachable = true;
|
||||
}
|
||||
self.infer_standalone_expression(test);
|
||||
self.infer_body(body);
|
||||
self.is_unreachable = false; // TODO handle nested unreachable code;
|
||||
|
||||
for clause in elif_else_clauses {
|
||||
let ast::ElifElseClause {
|
||||
@@ -1684,16 +1655,9 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
let value = assignment.value();
|
||||
let name = assignment.name();
|
||||
|
||||
dbg!(name, value);
|
||||
|
||||
self.infer_standalone_expression(value);
|
||||
|
||||
let value_ty = if dbg!(self.is_unreachable) {
|
||||
self.expression_ty(value);
|
||||
Type::Never
|
||||
} else {
|
||||
self.expression_ty(value)
|
||||
};
|
||||
let value_ty = self.expression_ty(value);
|
||||
let name_ast_id = name.scoped_expression_id(self.db, self.scope());
|
||||
|
||||
let target_ty = match assignment.target() {
|
||||
@@ -1710,8 +1674,6 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
TargetKind::Name => value_ty,
|
||||
};
|
||||
|
||||
dbg!(target_ty);
|
||||
|
||||
self.store_expression_type(name, target_ty);
|
||||
self.add_binding(name.into(), definition, target_ty);
|
||||
}
|
||||
@@ -2290,11 +2252,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
ty
|
||||
}
|
||||
|
||||
fn store_expression_type(
|
||||
&mut self,
|
||||
expression: &(impl HasScopedExpressionId + std::fmt::Debug),
|
||||
ty: Type<'db>,
|
||||
) {
|
||||
fn store_expression_type(&mut self, expression: &impl HasScopedExpressionId, ty: Type<'db>) {
|
||||
if self.deferred_state.in_string_annotation() {
|
||||
// Avoid storing the type of expressions that are part of a string annotation because
|
||||
// the expression ids don't exists in the semantic index. Instead, we'll store the type
|
||||
@@ -2302,15 +2260,6 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
return;
|
||||
}
|
||||
let expr_id = expression.scoped_expression_id(self.db, self.scope());
|
||||
dbg!(
|
||||
"Storing type for expression",
|
||||
expr_id,
|
||||
expression,
|
||||
ty.display(self.db)
|
||||
);
|
||||
|
||||
eprintln!("{}", std::backtrace::Backtrace::force_capture());
|
||||
|
||||
let previous = self.types.expressions.insert(expr_id, ty);
|
||||
assert_eq!(previous, None);
|
||||
}
|
||||
@@ -2661,7 +2610,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
// See https://peps.python.org/pep-0572/#differences-between-assignment-expressions-and-assignment-statements
|
||||
if named.target.is_name_expr() {
|
||||
let definition = self.index.definition(named);
|
||||
let result = infer_definition_types(self.db, definition, self.is_unreachable);
|
||||
let result = infer_definition_types(self.db, definition);
|
||||
self.extend(result);
|
||||
result.binding_ty(definition)
|
||||
} else {
|
||||
@@ -2887,11 +2836,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
let (bindings_ty, boundness) = if self.is_deferred() {
|
||||
if let Some(symbol) = self.index.symbol_table(file_scope_id).symbol_id_by_name(id) {
|
||||
(
|
||||
bindings_ty(
|
||||
self.db,
|
||||
use_def.public_bindings(symbol),
|
||||
self.is_unreachable,
|
||||
),
|
||||
bindings_ty(self.db, use_def.public_bindings(symbol)),
|
||||
use_def.public_boundness(symbol),
|
||||
)
|
||||
} else {
|
||||
@@ -2904,11 +2849,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
} else {
|
||||
let use_id = name.scoped_use_id(self.db, self.scope());
|
||||
(
|
||||
bindings_ty(
|
||||
self.db,
|
||||
use_def.bindings_at_use(use_id),
|
||||
self.is_unreachable,
|
||||
),
|
||||
bindings_ty(self.db, use_def.bindings_at_use(use_id)),
|
||||
use_def.use_boundness(use_id),
|
||||
)
|
||||
};
|
||||
@@ -6247,12 +6188,12 @@ mod tests {
|
||||
|
||||
let events = db.take_salsa_events();
|
||||
|
||||
// assert_function_query_was_not_run(
|
||||
// &db,
|
||||
// infer_definition_types,
|
||||
// first_public_binding(&db, a, "x"),
|
||||
// &events,
|
||||
// );
|
||||
assert_function_query_was_not_run(
|
||||
&db,
|
||||
infer_definition_types,
|
||||
first_public_binding(&db, a, "x"),
|
||||
&events,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -6283,12 +6224,12 @@ mod tests {
|
||||
|
||||
let events = db.take_salsa_events();
|
||||
|
||||
// assert_function_query_was_not_run(
|
||||
// &db,
|
||||
// infer_definition_types,
|
||||
// first_public_binding(&db, a, "x"),
|
||||
// &events,
|
||||
// );
|
||||
assert_function_query_was_not_run(
|
||||
&db,
|
||||
infer_definition_types,
|
||||
first_public_binding(&db, a, "x"),
|
||||
&events,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user