@@ -699,9 +699,13 @@ class PreTypeMention = PreTypeMention::TypeMention;
699699/**
700700 * Holds if `path` accesses an associated type `alias` from `trait` on a
701701 * concrete type given by `tm`.
702+ *
703+ * `implOrTmTrait` is either the mention that resolves to `trait` when `path`
704+ * is of the form `<Type as Trait>::AssocType`, or the enclosing `impl` block
705+ * when `path` is of the form `Self::AssocType`.
702706 */
703707private predicate pathConcreteTypeAssocType (
704- Path path , PreTypeMention tm , TraitItemNode trait , PreTypeMention tmTrait , TypeAlias alias
708+ Path path , PreTypeMention tm , TraitItemNode trait , AstNode implOrTmTrait , TypeAlias alias
705709) {
706710 exists ( Path qualifier |
707711 qualifier = path .getQualifier ( ) and
@@ -710,19 +714,19 @@ private predicate pathConcreteTypeAssocType(
710714 // path of the form `<Type as Trait>::AssocType`
711715 // ^^^ tm ^^^^^^^^^ name
712716 exists ( string name |
713- pathTypeAsTraitAssoc ( path , tm , tmTrait , trait , name ) and
717+ pathTypeAsTraitAssoc ( path , tm , implOrTmTrait , trait , name ) and
714718 getTraitAssocType ( trait , name ) = alias
715719 )
716720 or
717721 // path of the form `Self::AssocType` within an `impl` block
718722 // tm ^^^^ ^^^^^^^^^ name
719- exists ( ImplItemNode impl |
720- alias = resolvePath ( path ) and
721- qualifier = impl . getASelfPath ( ) and
722- tm = impl .( Impl ) . getSelfTy ( ) and
723- trait . getAnAssocItem ( ) = alias and
724- tmTrait = impl . getTraitPath ( )
725- )
723+ implOrTmTrait =
724+ any ( ImplItemNode impl |
725+ alias = resolvePath ( path ) and
726+ qualifier = impl .getASelfPath ( ) and
727+ tm = impl . ( Impl ) . getSelfTy ( ) and
728+ trait . getAnAssocItem ( ) = alias
729+ )
726730 )
727731}
728732
@@ -741,21 +745,26 @@ private module PathSatisfiesConstraint =
741745 */
742746private Type getPathConcreteAssocTypeAt ( Path path , TypePath typePath ) {
743747 exists (
744- PreTypeMention tm , ImplItemNode impl , TraitItemNode trait , TraitType t , PreTypeMention tmTrait ,
748+ PreTypeMention tm , ImplItemNode impl , TraitItemNode trait , TraitType t , AstNode implOrTmTrait ,
745749 TypeAlias alias , TypePath path0
746750 |
747- pathConcreteTypeAssocType ( path , tm , trait , tmTrait , alias ) and
751+ pathConcreteTypeAssocType ( path , tm , trait , implOrTmTrait , alias ) and
748752 t = TTrait ( trait ) and
749753 PathSatisfiesConstraint:: satisfiesConstraintTypeThrough ( tm , impl , t , path0 , result ) and
750754 path0 .isCons ( TAssociatedTypeTypeParameter ( trait , alias ) , typePath )
751755 |
752- tmTrait . getTypeAt ( TypePath :: nil ( ) ) != t
756+ implOrTmTrait instanceof Impl
753757 or
754- not exists ( TypePath path1 , Type t1 |
755- t1 = impl .getTraitPath ( ) .( PreTypeMention ) .getTypeAt ( path1 ) and
756- not t1 instanceof TypeParameter and
757- t1 != tmTrait .getTypeAt ( path1 )
758- )
758+ // When `path` is of the form `<Type as Trait>::AssocType` we need to check
759+ // that `impl` is not more specific than the mentioned trait
760+ implOrTmTrait =
761+ any ( PreTypeMention tmTrait |
762+ not exists ( TypePath path1 , Type t1 |
763+ t1 = impl .getTraitPath ( ) .( PreTypeMention ) .getTypeAt ( path1 ) and
764+ not t1 instanceof TypeParameter and
765+ t1 != tmTrait .getTypeAt ( path1 )
766+ )
767+ )
759768 )
760769}
761770
0 commit comments