@@ -501,20 +501,26 @@ You can use a type union to explicitly restrict the permitted branches from an a
501501and resolve spurious :ref: `recursion <recursion >` in predicates.
502502For example, the following construction is legal::
503503
504- newtype T =
505- T1(T t) { not exists(T2orT3 s | t = s) } or
506- T2(int x) { x = 1 or x = 2 } or
507- T3(int x) { x = 3 or x = 4 or x = 5 }
504+ newtype InitialValueSource =
505+ ExplicitInitialization(VarDecl v) { exists(v.getInitializer()) } or
506+ ParameterPassing(Call c, int pos) { exists(c.getParameter(pos)) } or
507+ UnknownInitialGarbage(VarDecl v) { not exists(DefiniteInitialization di | v = target(di)) }
508+
509+ class DefiniteInitialization = ParameterPassing or ExplicitInitialization;
508510
509- class T2orT3 = T2 or T3;
511+ VarDecl target(DefiniteInitialization di) {
512+ di = ExplicitInitialization(result) or
513+ exists(Call c, int pos | di = ParameterPassing(c, pos) and
514+ result = c.getCallee().getFormalArg(pos))
515+ }
510516
511- However, a similar implementation that restricts ``T `` in a class extension is not valid.
512- The class ``T2orT3 `` triggers a type test for ``T ``, which results in an illegal recursion
513- ``T2orT3 -> T -> T1 -> ¬T2orT3 `` since ``T1 `` relies on ``T2orT3 ``::
517+ However, a similar implementation that restricts ``InitialValueSource `` in a class extension is not valid.
518+ The class ``DefiniteInitialization `` triggers a type test for ``InitialValueSource ``, which results in an illegal recursion
519+ ``DefiniteInitialization -> InitialValueSource -> UnknownInitialGarbage -> ¬DefiniteInitialization `` since ``UnknownInitialGarbage `` relies on ``DefiniteInitialization ``::
514520
515- class T2orT3 extends T {
516- T2orT3 () {
517- this instanceof T2 or this instanceof T3
521+ class DefiniteInitialization extends InitialValueSource {
522+ DefiniteInitialization () {
523+ this instanceof ParameterPassing or this instanceof ExplicitInitialization
518524 }
519525 // ...
520526 }
0 commit comments