@@ -522,16 +522,21 @@ module Gvn {
522522
523523/** Provides definitions related to type unification. */
524524module Unification {
525- /** A type parameter that is compatible with any type. */
525+ /** A type parameter that is compatible with any type except `ref struct` . */
526526 class UnconstrainedTypeParameter extends TypeParameter {
527- UnconstrainedTypeParameter ( ) { not exists ( getATypeConstraint ( this ) ) }
527+ UnconstrainedTypeParameter ( ) {
528+ not exists ( getATypeConstraint ( this ) ) and not exists ( getANegativeTypeConstraint ( this ) )
529+ }
528530 }
529531
530532 /** A type parameter that is constrained. */
531533 class ConstrainedTypeParameter extends TypeParameter {
532534 int constraintCount ;
533535
534- ConstrainedTypeParameter ( ) { constraintCount = strictcount ( getATypeConstraint ( this ) ) }
536+ ConstrainedTypeParameter ( ) {
537+ constraintCount = count ( getATypeConstraint ( this ) ) + count ( getANegativeTypeConstraint ( this ) ) and
538+ constraintCount > 0
539+ }
535540
536541 /**
537542 * Holds if this type parameter is unifiable with type `t`.
@@ -559,29 +564,31 @@ module Unification {
559564 bindingset [ this ]
560565 pragma [ inline_late]
561566 override predicate unifiable ( Type t ) {
562- exists ( TTypeParameterConstraint ttc | ttc = getATypeConstraint ( this ) |
567+ forall ( TTypeParameterConstraint ttc | ttc = getATypeConstraint ( this ) |
563568 ttc = TRefTypeConstraint ( ) and
564569 t .isRefType ( )
565570 or
566571 ttc = TValueTypeConstraint ( ) and
567572 t .isValueType ( )
568573 or
569574 typeConstraintUnifiable ( ttc , t )
570- )
575+ ) and
576+ ( t .isRefLikeType ( ) implies getANegativeTypeConstraint ( this ) = TAllowRefTypeConstraint ( ) )
571577 }
572578
573579 bindingset [ this ]
574580 pragma [ inline_late]
575581 override predicate subsumes ( Type t ) {
576- exists ( TTypeParameterConstraint ttc | ttc = getATypeConstraint ( this ) |
582+ forall ( TTypeParameterConstraint ttc | ttc = getATypeConstraint ( this ) |
577583 ttc = TRefTypeConstraint ( ) and
578584 t .isRefType ( )
579585 or
580586 ttc = TValueTypeConstraint ( ) and
581587 t .isValueType ( )
582588 or
583589 typeConstraintSubsumes ( ttc , t )
584- )
590+ ) and
591+ ( t .isRefLikeType ( ) implies getANegativeTypeConstraint ( this ) = TAllowRefTypeConstraint ( ) )
585592 }
586593 }
587594
@@ -603,7 +610,8 @@ module Unification {
603610 t .isValueType ( )
604611 or
605612 typeConstraintUnifiable ( ttc , t )
606- )
613+ ) and
614+ ( t .isRefLikeType ( ) implies getANegativeTypeConstraint ( this ) = TAllowRefTypeConstraint ( ) )
607615 }
608616
609617 bindingset [ this ]
@@ -617,7 +625,8 @@ module Unification {
617625 t .isValueType ( )
618626 or
619627 typeConstraintSubsumes ( ttc , t )
620- )
628+ ) and
629+ ( t .isRefLikeType ( ) implies getANegativeTypeConstraint ( this ) = TAllowRefTypeConstraint ( ) )
621630 }
622631 }
623632
@@ -632,6 +641,9 @@ module Unification {
632641 not t instanceof TypeParameter
633642 }
634643
644+ cached
645+ newtype TTypeParameterNegativeConstraint = TAllowRefTypeConstraint ( )
646+
635647 cached
636648 TTypeParameterConstraint getATypeConstraint ( TypeParameter tp ) {
637649 exists ( TypeParameterConstraints tpc | tpc = tp .getConstraints ( ) |
@@ -650,6 +662,14 @@ module Unification {
650662 )
651663 }
652664
665+ cached
666+ TTypeParameterNegativeConstraint getANegativeTypeConstraint ( TypeParameter tp ) {
667+ exists ( TypeParameterConstraints tpc | tpc = tp .getConstraints ( ) |
668+ tpc .hasAllowRefLikeTypeConstraint ( ) and
669+ result = TAllowRefTypeConstraint ( )
670+ )
671+ }
672+
653673 cached
654674 predicate typeConstraintUnifiable ( TTypeConstraint ttc , Type t ) {
655675 exists ( Type t0 | ttc = TTypeConstraint ( t0 ) | implicitConversionRestricted ( t , t0 ) )
0 commit comments