Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hasMatchingMember handling NoDenotation #17977

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ object Denotations {
/** Does this denotation have an alternative that satisfies the predicate `p`? */
def hasAltWith(p: SingleDenotation => Boolean): Boolean

inline final def hasAltWithInline(inline p: SingleDenotation => Boolean): Boolean = inline this match
case mbr: SingleDenotation => mbr.exists && p(mbr)
case mbr => mbr.hasAltWith(p)

/** The denotation made up from the alternatives of this denotation that
* are accessible from prefix `pre`, or NoDenotation if no accessible alternative exists.
*/
Expand Down
4 changes: 1 addition & 3 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2020,9 +2020,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
|| matchAbstractTypeMember(m.info)
|| (tp1.isStable && isSubType(TermRef(tp1, m.symbol), tp2.refinedInfo))

tp1.member(name) match // inlined hasAltWith for performance
case mbr: SingleDenotation => qualifies(mbr)
case mbr => mbr hasAltWith qualifies
tp1.member(name).hasAltWithInline(qualifies)
}

final def ensureStableSingleton(tp: Type): SingletonType = tp.stripTypeVar match {
Expand Down
5 changes: 1 addition & 4 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1517,10 +1517,7 @@ trait Applications extends Compatibility {
&& isApplicableType(
normalize(tp.select(xname, mbr), WildcardType),
argType :: Nil, resultType)
tp.memberBasedOnFlags(xname, required = ExtensionMethod) match {
case mbr: SingleDenotation => qualifies(mbr)
case mbr => mbr.hasAltWith(qualifies(_))
}
tp.memberBasedOnFlags(xname, required = ExtensionMethod).hasAltWithInline(qualifies)
}

/** Drop any leading type or implicit parameter sections */
Expand Down
4 changes: 1 addition & 3 deletions compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,7 @@ object ProtoTypes {
|| tp1.isValueType && compat.normalizedCompatible(NamedType(tp1, name, m), memberProto, keepConstraint))
// Note: can't use `m.info` here because if `m` is a method, `m.info`
// loses knowledge about `m`'s default arguments.
mbr match // hasAltWith inlined for performance
case mbr: SingleDenotation => mbr.exists && qualifies(mbr)
case _ => mbr hasAltWith qualifies
mbr.hasAltWithInline(qualifies)
catch case ex: TypeError =>
// A scenario where this can happen is in pos/15673.scala:
// We have a type `CC[A]#C` where `CC`'s upper bound is `[X] => Any`, but
Expand Down
7 changes: 7 additions & 0 deletions tests/neg/i17581.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- [E007] Type Mismatch Error: tests/neg/i17581.scala:9:6 --------------------------------------------------------------
9 | foo(test) // error // was NoSuchMethodException
| ^^^^
| Found: (test : Test)
| Required: Object{def bar: Any}
|
| longer explanation available when compiling with `-explain`
9 changes: 9 additions & 0 deletions tests/neg/i17581.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import scala.reflect.Selectable.reflectiveSelectable

class Test

def foo[A <: { def bar: Any }](ob: A) = ob.bar

@main def main =
val test = new Test
foo(test) // error // was NoSuchMethodException
2 changes: 1 addition & 1 deletion tests/neg/i7812.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
def f(): Any = ???
var f: (UndefinedA & UndefinedB) { val x: Int } = ??? // error // error
val a = f // error
val a = f