@@ -4,9 +4,10 @@ use crate::dunder_all::dunder_all_names;
4
4
use crate :: module_resolver:: { KnownModule , file_to_module} ;
5
5
use crate :: semantic_index:: definition:: { Definition , DefinitionState } ;
6
6
use crate :: semantic_index:: place:: { PlaceExprRef , ScopedPlaceId } ;
7
- use crate :: semantic_index:: scope:: ScopeId ;
7
+ use crate :: semantic_index:: scope:: { ScopeId , ScopeLaziness } ;
8
8
use crate :: semantic_index:: {
9
- BindingWithConstraints , BindingWithConstraintsIterator , DeclarationsIterator , place_table,
9
+ BindingWithConstraints , BindingWithConstraintsIterator , BoundnessAnalysis ,
10
+ ConsideredDefinitions , DeclarationsIterator , EnclosingSnapshotResult , place_table,
10
11
} ;
11
12
use crate :: semantic_index:: { DeclarationWithConstraint , global_scope, use_def_map} ;
12
13
use crate :: types:: {
@@ -293,7 +294,7 @@ pub(crate) fn explicit_global_symbol<'db>(
293
294
global_scope ( db, file) ,
294
295
name,
295
296
RequiresExplicitReExport :: No ,
296
- ConsideredDefinitions :: AllReachable ,
297
+ ConsideredDefinitions :: AllReachable ( None ) ,
297
298
)
298
299
}
299
300
@@ -700,15 +701,24 @@ fn place_by_id<'db>(
700
701
701
702
let declarations = match considered_definitions {
702
703
ConsideredDefinitions :: EndOfScope => use_def. end_of_scope_declarations ( place_id) ,
703
- ConsideredDefinitions :: AllReachable => use_def. all_reachable_declarations ( place_id) ,
704
+ ConsideredDefinitions :: AllReachable ( _ ) => use_def. all_reachable_declarations ( place_id) ,
704
705
} ;
705
706
706
707
let declared = place_from_declarations_impl ( db, declarations, requires_explicit_reexport)
707
708
. ignore_conflicting_declarations ( ) ;
708
709
709
710
let all_considered_bindings = || match considered_definitions {
710
711
ConsideredDefinitions :: EndOfScope => use_def. end_of_scope_bindings ( place_id) ,
711
- ConsideredDefinitions :: AllReachable => use_def. all_reachable_bindings ( place_id) ,
712
+ ConsideredDefinitions :: AllReachable ( None ) => use_def. all_reachable_bindings ( place_id) ,
713
+ ConsideredDefinitions :: AllReachable ( Some ( snapshot) ) => {
714
+ if let EnclosingSnapshotResult :: FoundBindings ( bindings, _) =
715
+ use_def. enclosing_snapshot ( snapshot, ScopeLaziness :: Lazy )
716
+ {
717
+ bindings
718
+ } else {
719
+ use_def. all_reachable_bindings ( place_id)
720
+ }
721
+ }
712
722
} ;
713
723
714
724
// If a symbol is undeclared, but qualified with `typing.Final`, we use the right-hand side
@@ -763,7 +773,7 @@ fn place_by_id<'db>(
763
773
// Place is possibly undeclared and (possibly) bound
764
774
Place :: Type ( inferred_ty, boundness) => Place :: Type (
765
775
UnionType :: from_elements ( db, [ inferred_ty, declared_ty] ) ,
766
- if boundness_analysis == BoundnessAnalysis :: AssumeBound {
776
+ if boundness_analysis. is_assume_bound ( ) {
767
777
Boundness :: Bound
768
778
} else {
769
779
boundness
@@ -782,7 +792,7 @@ fn place_by_id<'db>(
782
792
let boundness_analysis = bindings. boundness_analysis ;
783
793
let mut inferred = place_from_bindings_impl ( db, bindings, requires_explicit_reexport) ;
784
794
785
- if boundness_analysis == BoundnessAnalysis :: AssumeBound {
795
+ if boundness_analysis. is_assume_bound ( ) {
786
796
if let Place :: Type ( ty, Boundness :: PossiblyUnbound ) = inferred {
787
797
inferred = Place :: Type ( ty, Boundness :: Bound ) ;
788
798
}
@@ -1037,7 +1047,7 @@ fn place_from_bindings_impl<'db>(
1037
1047
} ;
1038
1048
1039
1049
let boundness = match boundness_analysis {
1040
- BoundnessAnalysis :: AssumeBound => Boundness :: Bound ,
1050
+ BoundnessAnalysis :: AssumeBound ( _ ) => Boundness :: Bound ,
1041
1051
BoundnessAnalysis :: BasedOnUnboundVisibility => match unbound_visibility ( ) {
1042
1052
Some ( Truthiness :: AlwaysTrue ) => {
1043
1053
unreachable ! (
@@ -1245,7 +1255,7 @@ fn place_from_declarations_impl<'db>(
1245
1255
} ;
1246
1256
1247
1257
let boundness = match boundness_analysis {
1248
- BoundnessAnalysis :: AssumeBound => {
1258
+ BoundnessAnalysis :: AssumeBound ( _ ) => {
1249
1259
if all_declarations_definitely_reachable {
1250
1260
Boundness :: Bound
1251
1261
} else {
@@ -1458,48 +1468,6 @@ impl RequiresExplicitReExport {
1458
1468
}
1459
1469
}
1460
1470
1461
- /// Specifies which definitions should be considered when looking up a place.
1462
- ///
1463
- /// In the example below, the `EndOfScope` variant would consider the `x = 2` and `x = 3` definitions,
1464
- /// while the `AllReachable` variant would also consider the `x = 1` definition.
1465
- /// ```py
1466
- /// def _():
1467
- /// x = 1
1468
- ///
1469
- /// x = 2
1470
- ///
1471
- /// if flag():
1472
- /// x = 3
1473
- /// ```
1474
- #[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash , salsa:: Update ) ]
1475
- pub ( crate ) enum ConsideredDefinitions {
1476
- /// Consider only the definitions that are "live" at the end of the scope, i.e. those
1477
- /// that have not been shadowed or deleted.
1478
- EndOfScope ,
1479
- /// Consider all definitions that are reachable from the start of the scope.
1480
- AllReachable ,
1481
- }
1482
-
1483
- /// Specifies how the boundness of a place should be determined.
1484
- #[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash , salsa:: Update ) ]
1485
- pub ( crate ) enum BoundnessAnalysis {
1486
- /// The place is always considered bound.
1487
- AssumeBound ,
1488
- /// The boundness of the place is determined based on the visibility of the implicit
1489
- /// `unbound` binding. In the example below, when analyzing the visibility of the
1490
- /// `x = <unbound>` binding from the position of the end of the scope, it would be
1491
- /// `Truthiness::Ambiguous`, because it could either be visible or not, depending on the
1492
- /// `flag()` return value. This would result in a `Boundness::PossiblyUnbound` for `x`.
1493
- ///
1494
- /// ```py
1495
- /// x = <unbound>
1496
- ///
1497
- /// if flag():
1498
- /// x = 1
1499
- /// ```
1500
- BasedOnUnboundVisibility ,
1501
- }
1502
-
1503
1471
/// Computes a possibly-widened type `Unknown | T_inferred` from the inferred type `T_inferred`
1504
1472
/// of a symbol, unless the type is a known-instance type (e.g. `typing.Any`) or the symbol is
1505
1473
/// considered non-modifiable (e.g. when the symbol is `@Final`). We need this for public uses
0 commit comments