Skip to content

Commit bbb70cc

Browse files
authored
Fix hasMatchingMember handling NoDenotation (#17977)
Fixes #17581
2 parents 045f3e8 + 4373d48 commit bbb70cc

File tree

7 files changed

+24
-11
lines changed

7 files changed

+24
-11
lines changed

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ object Denotations {
261261
/** Does this denotation have an alternative that satisfies the predicate `p`? */
262262
def hasAltWith(p: SingleDenotation => Boolean): Boolean
263263

264+
inline final def hasAltWithInline(inline p: SingleDenotation => Boolean): Boolean = inline this match
265+
case mbr: SingleDenotation => mbr.exists && p(mbr)
266+
case mbr => mbr.hasAltWith(p)
267+
264268
/** The denotation made up from the alternatives of this denotation that
265269
* are accessible from prefix `pre`, or NoDenotation if no accessible alternative exists.
266270
*/

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,9 +2031,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
20312031
|| matchAbstractTypeMember(m.info)
20322032
|| (tp1.isStable && m.symbol.isStableMember && isSubType(TermRef(tp1, m.symbol), tp2.refinedInfo))
20332033

2034-
tp1.member(name) match // inlined hasAltWith for performance
2035-
case mbr: SingleDenotation => qualifies(mbr)
2036-
case mbr => mbr hasAltWith qualifies
2034+
tp1.member(name).hasAltWithInline(qualifies)
20372035
}
20382036

20392037
final def ensureStableSingleton(tp: Type): SingletonType = tp.stripTypeVar match {

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,10 +1517,7 @@ trait Applications extends Compatibility {
15171517
&& isApplicableType(
15181518
normalize(tp.select(xname, mbr), WildcardType),
15191519
argType :: Nil, resultType)
1520-
tp.memberBasedOnFlags(xname, required = ExtensionMethod) match {
1521-
case mbr: SingleDenotation => qualifies(mbr)
1522-
case mbr => mbr.hasAltWith(qualifies(_))
1523-
}
1520+
tp.memberBasedOnFlags(xname, required = ExtensionMethod).hasAltWithInline(qualifies)
15241521
}
15251522

15261523
/** Drop any leading type or implicit parameter sections */

compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,7 @@ object ProtoTypes {
212212
|| tp1.isValueType && compat.normalizedCompatible(NamedType(tp1, name, m), memberProto, keepConstraint))
213213
// Note: can't use `m.info` here because if `m` is a method, `m.info`
214214
// loses knowledge about `m`'s default arguments.
215-
mbr match // hasAltWith inlined for performance
216-
case mbr: SingleDenotation => mbr.exists && qualifies(mbr)
217-
case _ => mbr hasAltWith qualifies
215+
mbr.hasAltWithInline(qualifies)
218216
catch case ex: TypeError =>
219217
// A scenario where this can happen is in pos/15673.scala:
220218
// We have a type `CC[A]#C` where `CC`'s upper bound is `[X] => Any`, but

tests/neg/i17581.check

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- [E007] Type Mismatch Error: tests/neg/i17581.scala:9:6 --------------------------------------------------------------
2+
9 | foo(test) // error // was NoSuchMethodException
3+
| ^^^^
4+
| Found: (test : Test)
5+
| Required: Object{def bar: Any}
6+
|
7+
| longer explanation available when compiling with `-explain`

tests/neg/i17581.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import scala.reflect.Selectable.reflectiveSelectable
2+
3+
class Test
4+
5+
def foo[A <: { def bar: Any }](ob: A) = ob.bar
6+
7+
@main def main =
8+
val test = new Test
9+
foo(test) // error // was NoSuchMethodException

tests/neg/i7812.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
def f(): Any = ???
22
var f: (UndefinedA & UndefinedB) { val x: Int } = ??? // error // error
3-
val a = f // error
3+
val a = f

0 commit comments

Comments
 (0)