@@ -108,8 +108,8 @@ that assignment).
108108- Lists
109109 - We use the notation ` [a, b] ` to denote a list containing elements ` a ` and
110110 ` b ` .
111- - We use the notation ` a::l ` where ` l ` is a list to denote a list beginning
112- with ` a ` and followed by all of the elements of ` l ` .
111+ - We use the notation ` [...l, a] ` where ` l ` is a list to denote a list
112+ beginning with all the elements of ` l ` and followed by ` a ` .
113113
114114- Stacks
115115 - We use the notation ` push(s, x) ` to mean pushing ` x ` onto the top of the
@@ -118,8 +118,8 @@ that assignment).
118118 the top element of ` s ` . If ` s ` is empty, the result is undefined.
119119 - We use the notation ` top(s) ` to mean the top element of the stack ` s ` . If
120120 ` s ` is empty, the result is undefined.
121- - Informally, we also use ` a::t ` to describe a stack ` s ` such that ` top(s) ` is
122- ` a ` and ` pop(s) ` is ` t ` .
121+ - Informally, we also use ` [...t, a] ` to describe a stack ` s ` such that
122+ ` top(s) ` is ` a ` and ` pop(s) ` is ` t ` .
123123
124124### Models
125125
@@ -131,10 +131,10 @@ source code.
131131- ` declaredType ` is the type assigned to the variable at its declaration site
132132 (either explicitly or by type inference).
133133
134- - ` promotedTypes ` is an ordered set of types that the variable has been promoted
135- to, with the final entry in the ordered set being the current promoted type of
136- the variable. Note that each entry in the ordered set must be a subtype of
137- all previous entries , and of the declared type.
134+ - ` promotedTypes ` is a list of types that the variable has been promoted to,
135+ with the final type in the list being the current promoted type of the
136+ variable. Note that each type in the list must be a subtype of all previous
137+ types , and of the declared type.
138138
139139- ` tested ` is a set of types which are considered "of interest" for the purposes
140140 of promotion, generally because the variable in question has been tested
@@ -238,9 +238,14 @@ We also make use of the following auxiliary functions:
238238 - ` VM3 = VariableModel(d3, p3, s3, a3, u3, c3) ` where
239239 - ` d3 = d1 = d2 `
240240 - Note that all models must agree on the declared type of a variable
241- - ` p3 = p1 ^ p2 `
242- - ` p1 ` and ` p2 ` are totally ordered subsets of a global partial order.
243- Their intersection is a subset of each, and as such is also totally ordered.
241+ - ` p3 ` is a list formed by taking all the types that are in both ` p1 ` and
242+ ` p2 ` , and ordering them such that each type in the list is a subtype of all
243+ previous types.
244+ - _ Note: it is not specified how to order elements of this list that are
245+ mutual subtypes of each other. This will soon be addressed by changing
246+ the behavior of flow analysis so that each type in the list is a proper
247+ subtype of the previous. (See
248+ https://github.com/dart-lang/language/issues/4368 .)
244249 - ` s3 = s1 U s2 `
245250 - The set of test sites is the union of the test sites on either path
246251 - ` a3 = a1 && a2 `
@@ -258,14 +263,14 @@ We also make use of the following auxiliary functions:
258263 where ` r2 ` is ` r ` with ` true ` pushed as the top element of the stack.
259264
260265- ` drop(M) ` , where ` M = FlowModel(r, VM) ` is defined as ` FlowModel(r1, VM) `
261- where ` r ` is of the form ` n0::r1 ` . This is the flow model which drops
266+ where ` r ` is of the form ` [...r1, n0] ` . This is the flow model which drops
262267 the reachability information encoded in the top entry in the stack.
263268
264269- ` unsplit(M) ` , where ` M = FlowModel(r, VM) ` is defined as `M1 = FlowModel(r1,
265- VM)` where ` r` is of the form ` n0::n1::s ` and ` r1 = ( n0&&n1)::s `. The model
266- ` M1 ` is a flow model which collapses the top two elements of the reachability
267- model from ` M ` into a single boolean which conservatively summarizes the
268- reachability information present in ` M ` .
270+ VM)` where ` r` is of the form ` [ ...s, n1, n0 ] ` and ` r1 = [ ...s, n0&&n1] `. The
271+ model ` M1 ` is a flow model which collapses the top two elements of the
272+ reachability model from ` M ` into a single boolean which conservatively
273+ summarizes the reachability information present in ` M ` .
269274
270275- ` merge(M1, M2) ` , where ` M1 ` and ` M2 ` are flow models is the inverse of ` split `
271276 and represents the result of joining two flow models at the merge of two
@@ -393,7 +398,7 @@ Promotion policy is defined by the following operations on flow models.
393398
394399We say that the ** current type** of a variable ` x ` in variable model ` VM ` is ` S ` where:
395400 - ` VM = VariableModel(declared, promoted, tested, assigned, unassigned, captured) `
396- - ` promoted = S::l ` or (` promoted = [] ` and ` declared = S ` )
401+ - ` promoted = [...l, S] ` or (` promoted = [] ` and ` declared = S ` )
397402
398403Policy:
399404 - We say that at type ` T ` is a type of interest for a variable ` x ` in a set of
@@ -421,8 +426,8 @@ Policy:
421426 type ` T ` given variable model ` VM ` if
422427 - ` VM = VariableModel(declared, promoted, tested, assigned, unassigned, captured) `
423428 - and ` captured ` is false
424- - and declared:: promoted contains a type ` S ` such that ` T ` is ` S ` or ` T ` is
425- ** NonNull(` S ` )** .
429+ - and [ ... promoted, declared ] contains a type ` S ` such that ` T ` is ` S ` or
430+ ` T ` is ** NonNull(` S ` )** .
426431
427432Definitions:
428433
@@ -433,13 +438,14 @@ Definitions:
433438 - if ` captured ` is true then:
434439 - ` VM = VariableModel(declared, promoted, tested, true, false, captured) ` .
435440 - otherwise if ` x ` is promotable via assignment of ` E ` given ` VM `
436- - ` VM = VariableModel(declared, T::promoted, tested, true, false, captured) ` .
441+ - `VM = VariableModel(declared, [ ...promoted, T] , tested, true, false,
442+ captured)`.
437443 - otherwise if ` x ` is demotable via assignment of ` E ` given ` VM `
438444 - ` VM = VariableModel(declared, demoted, tested, true, false, captured) ` .
439- - where ` previous ` is the suffix of ` promoted ` starting with the first type
445+ - where ` previous ` is the prefix of ` promoted ` ending with the first type
440446 ` S ` such that ` T <: S ` , and:
441- - if ` S ` is nullable and if ` T <: Q ` where ` Q ` is ** NonNull(` S ` )** then
442- ` demoted ` is ` Q:: previous`
447+ - if ` S ` is nullable and if ` T <: Q ` where ` Q ` is ** NonNull(` S ` )** then
448+ ` demoted ` is ` [... previous, Q] `
443449 - otherwise ` demoted ` is ` previous `
444450
445451- ` stripParens(E1) ` , where ` E1 ` is an expression, is the result of stripping
@@ -467,8 +473,8 @@ Definitions:
467473 - Else if ` S ` is ` X extends R ` then let ` T1 ` = ` X & T `
468474 - Else If ` S ` is ` X & R ` then let ` T1 ` = ` X & T `
469475 - Else ` x ` is not promotable (shouldn't happen since we checked above)
470- - Let `VM2 = VariableModel(declared, T1:: promoted, T:: tested, assigned ,
471- unassigned, captured)`
476+ - Let `VM2 = VariableModel(declared, [ ... promoted, T1 ] , [ ... tested, T ] ,
477+ assigned, unassigned, captured)`
472478 - Let ` M2 = FlowModel(r, VI[x -> VM2]) `
473479 - If ` T1 <: Never ` then ` M3 ` = ` unreachable(M2) ` , otherwise ` M3 ` = ` M2 `
474480- ` promoteToNonNull(E, M) ` where ` E ` is an expression and ` M ` is a flow model is
0 commit comments