22
33import java .util .*;
44import edu .rice .cs .plt .tuple .Pair ;
5- import edu .rice .cs .plt .tuple .Triple ;
65import edu .rice .cs .plt .tuple .Option ;
76import edu .rice .cs .plt .tuple .Wrapper ;
87import edu .rice .cs .plt .recur .*;
2827
2928public class ExtendedTypeSystem extends StandardTypeSystem {
3029
31- public ExtendedTypeSystem (Options opt ) { super (opt ); }
30+ /** Whether the inference algorithm should attempt to pack capture variables that appear as inference results. */
31+ private final boolean _packCaptureVars ;
32+
33+ public ExtendedTypeSystem (Options opt ) { this (opt , true ); }
34+
35+ public ExtendedTypeSystem (Options opt , boolean packCaptureVars ) {
36+ super (opt );
37+ _packCaptureVars = packCaptureVars ;
38+ }
3239
3340 /** Determine if the type is well-formed. */
3441 public boolean isWellFormed (Type t ) {
@@ -134,7 +141,7 @@ public boolean contains(final Type subT, final Type superT) {
134141
135142 @ Override public Boolean forVariableType (final VariableType superT ) {
136143 return subT .apply (new TypeAbstractVisitor <Boolean >() {
137- public Boolean defaultCase (final Type subT ) {
144+ @ Override public Boolean defaultCase (final Type subT ) {
138145 Thunk <Boolean > checkLowerBound = new Thunk <Boolean >() {
139146 public Boolean value () {
140147 Type bound = new Normalizer (NormSubtyper .this ).value (superT .symbol ().lowerBound ());
@@ -152,23 +159,30 @@ public Boolean value() {
152159 @ Override public Boolean forIntersectionType (IntersectionType subT ) {
153160 return defaultCase (subT ) ? true : null ;
154161 }
162+ @ Override public Boolean forUnionType (UnionType subT ) { return null ; }
155163 @ Override public Boolean forBottomType (BottomType subT ) { return true ; }
156164 });
157165 }
158166
159- @ Override public Boolean forIntersectionType (IntersectionType superT ) {
160- if (subT instanceof BottomType ) { return true ; }
161- else { return IterUtil .and (superT .ofTypes (), supertypes (subT )); }
167+ @ Override public Boolean forIntersectionType (final IntersectionType superT ) {
168+ return subT .apply (new TypeAbstractVisitor <Boolean >() {
169+ @ Override public Boolean defaultCase (Type subT ) {
170+ return IterUtil .and (superT .ofTypes (), supertypes (subT ));
171+ }
172+ @ Override public Boolean forUnionType (UnionType subT ) { return null ; }
173+ @ Override public Boolean forBottomType (BottomType subT ) { return true ; }
174+ });
162175 }
163176
164177 @ Override public Boolean forUnionType (final UnionType superT ) {
165178 return subT .apply (new TypeAbstractVisitor <Boolean >() {
166179 @ Override public Boolean defaultCase (Type t ) {
167180 return IterUtil .or (superT .ofTypes (), supertypes (subT ));
168181 }
169- public Boolean forVariableType (VariableType t ) { return defaultCase (subT ) ? true : null ; }
170- public Boolean forUnionType (UnionType t ) { return null ; }
171- public Boolean forBottomType (BottomType t ) { return true ; }
182+ @ Override public Boolean forVariableType (VariableType t ) { return defaultCase (subT ) ? true : null ; }
183+ @ Override public Boolean forIntersectionType (IntersectionType t ) { return null ; }
184+ @ Override public Boolean forUnionType (UnionType t ) { return null ; }
185+ @ Override public Boolean forBottomType (BottomType t ) { return true ; }
172186 });
173187 }
174188
@@ -560,7 +574,7 @@ public String toString() {
560574 result .append ("{ " );
561575 boolean firstVar = true ;
562576 for (VariableType var : s .boundVariables ()) {
563- if (firstVar ) { result .append (", " ); }
577+ if (! firstVar ) { result .append (", " ); }
564578 firstVar = false ;
565579 result .append (printer .print (s .lowerBound (var )));
566580 result .append (" <: " );
@@ -765,7 +779,23 @@ protected Iterable<Type> inferTypeArguments(Iterable<? extends VariableType> tpa
765779 //debug.logValue("constraints", constraints);
766780 if (!transConstraints .isSatisfiable ()) { return null ; }
767781
768- // try to use lower bounds
782+ // try to use packed lower bounds
783+ if (_packCaptureVars ) {
784+ for (final ConstraintScenario s : transConstraints .scenarios ()) {
785+ Iterable <Type > result = IterUtil .mapSnapshot (tparams , new Lambda <VariableType , Type >() {
786+ public Type value (VariableType param ) {
787+ Type result = s .lowerBound (param );
788+ while (result instanceof VariableType && ((VariableType ) result ).symbol ().generated ()) {
789+ result = ((VariableType ) result ).symbol ().upperBound ();
790+ }
791+ return result ;
792+ }
793+ });
794+ if (inBounds (tparams , result )) { return result ; }
795+ }
796+ }
797+
798+ // packed lower bounds don't work, try to use lower bounds
769799 for (final ConstraintScenario s : transConstraints .scenarios ()) {
770800 Iterable <Type > result = IterUtil .mapSnapshot (tparams , new Lambda <VariableType , Type >() {
771801 public Type value (VariableType param ) { return s .lowerBound (param ); }
0 commit comments