@@ -414,39 +414,57 @@ Policy:
414
414
- and ` T <: S ` or (` S ` is ` X extends R ` and ` T <: R ` ) or (` S ` is ` X & R ` and
415
415
` T <: R ` )
416
416
417
- - We say that a variable ` x ` is promotable via assignment of an expression of
418
- type ` T ` given variable model ` VM ` if
419
- - ` VM = VariableModel(declared, promoted, tested, assigned, unassigned, captured) `
420
- - and ` captured ` is false
421
- - and ` S ` is the current type of ` x ` in ` VM `
422
- - and ` T <: S ` and not ` S <: T `
423
- - and ` T ` is a type of interest for ` x ` in ` tested `
424
-
425
- - We say that a variable ` x ` is demotable via assignment of an expression of
426
- type ` T ` given variable model ` VM ` if
427
- - ` VM = VariableModel(declared, promoted, tested, assigned, unassigned, captured) `
428
- - and ` captured ` is false
429
- - and [ ...promoted, declared] contains a type ` S ` such that ` T ` is ` S ` or
430
- ` T ` is ** NonNull(` S ` )** .
431
-
432
417
Definitions:
433
418
419
+ - ` currentType(declared, promoted) ` , where ` declared ` is a type and ` promoted `
420
+ is a list of types, is the type ` T ` , defined as follows:
421
+ - If ` promoted ` is ` [] ` , ` T ` is ` declared ` .
422
+ - Otherwise, ` T ` is the last type in the ` promoted ` list.
423
+
424
+ - ` demote(promoted, written) ` , where ` promoted ` is a list of types and ` written `
425
+ is a type, is a list containing all types ` T ` from ` promoted ` such that
426
+ ` written <: T ` . _ In effect, this removes any type promotions that are not
427
+ compatible with the ` written ` type._
428
+
429
+ - ` toi_promote(declared, demoted, tested, written) ` , where ` demoted ` and
430
+ ` tested ` are lists of types, and ` declared ` and ` written ` are types, is the
431
+ list ` promoted ` , defined as follows. _ ("toi" stands for "type of interest".)_
432
+ - Let ` p1 ` be a set containing the following types:
433
+ - ** NonNull** (` declared ` ), if it is not the same as ` declared ` .
434
+ - For each type ` T ` in the ` tested ` list:
435
+ - ` T `
436
+ - ** NonNull** (` T ` ), if it is not the same as ` T ` .
437
+
438
+ _ The types in ` p1 ` are known as the types of interest._
439
+ - Let ` p2 ` be the set ` p1 \ { currentType(declared, demoted) } ` _ (where ` \ `
440
+ denotes set subtraction)_ .
441
+ - If the ` written ` type is in ` p2 ` , then ` promoted ` is `[ demoted,
442
+ written] `. _ Writing a value whose static type is a type of interest promotes
443
+ to that type._
444
+ - Otherwise:
445
+ - Let ` p3 ` be the set of all types ` T ` in ` p2 ` such that `written <: T <:
446
+ currentType(declared, demoted)`.
447
+ - If ` p3 ` contains exactly one type ` T ` that is a subtype of all the others,
448
+ then ` promoted ` is ` [demoted, T] ` . _ Writing a value whose static type is
449
+ a subtype of a type of interest promotes to that type of interest,
450
+ provided there is a single "best" type of interest available to promote
451
+ to._
452
+ - Otherwise, ` promoted ` is ` demoted ` . _ If there is no single "best" type
453
+ of interest to promote to, then no type of interest promotion is done._
454
+
434
455
- ` assign(x, E, M) ` where ` x ` is a local variable, ` E ` is an expression of
435
456
inferred type ` T ` , and ` M = FlowModel(r, VI) ` is the flow model for ` E ` is
436
457
defined to be ` FlowModel(r, VI[x -> VM]) ` where:
437
- - ` VI(x) = VariableModel(declared, promoted, tested, assigned, unassigned, captured) `
438
- - if ` captured ` is true then:
439
- - ` VM = VariableModel(declared, promoted, tested, true, false, captured) ` .
440
- - otherwise if ` x ` is promotable via assignment of ` E ` given ` VM `
441
- - `VM = VariableModel(declared, [ ...promoted, T] , tested, true, false,
442
- captured)`.
443
- - otherwise if ` x ` is demotable via assignment of ` E ` given ` VM `
444
- - ` VM = VariableModel(declared, demoted, tested, true, false, captured) ` .
445
- - where ` previous ` is the prefix of ` promoted ` ending with the first type
446
- ` S ` such that ` T <: S ` , and:
447
- - if ` S ` is nullable and if ` T <: Q ` where ` Q ` is ** NonNull(` S ` )** then
448
- ` demoted ` is ` [...previous, Q] `
449
- - otherwise ` demoted ` is ` previous `
458
+ - `VI(x) = VariableModel(declared, promoted, tested, assigned, unassigned,
459
+ captured)`
460
+ - If ` captured ` is true then:
461
+ - ` VM = VariableModel(declared, promoted, tested, true, false, captured) ` .
462
+ - Otherwise:
463
+ - Let ` written = T ` .
464
+ - Let ` demoted = demote(promoted, written) ` .
465
+ - Let ` promoted' = toi_promote(declared, demoted, tested, written) ` .
466
+ - Then `VM = VariableModel(declared, promoted', tested, true, false,
467
+ captured)`.
450
468
451
469
- ` stripParens(E1) ` , where ` E1 ` is an expression, is the result of stripping
452
470
outer parentheses from the expression ` E1 ` . It is defined to be the
0 commit comments