Restore to main

This commit is contained in:
David Peter
2024-11-27 14:19:08 +01:00
parent 90f48f45b0
commit ae45b897ea
3 changed files with 32 additions and 96 deletions

View File

@@ -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)
}
}
};

View File

@@ -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(

View File

@@ -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(())
}
}