@@ -165,12 +165,12 @@ trait Typers { self: Analyzer =>
165
165
case OverloadedType (_, _) => EmptyTree
166
166
case PolyType (_, _) => EmptyTree
167
167
case _ =>
168
- val result = inferImplicit(pos, functionType (List (from), to), true , reportAmbiguous)
168
+ val result = inferImplicit(pos, MethodType (List (from), to), reportAmbiguous)
169
169
if (result != EmptyTree ) result
170
170
else inferImplicit(
171
171
pos,
172
- functionType (List (appliedType(ByNameParamClass .typeConstructor, List (from))), to),
173
- true , reportAmbiguous)
172
+ MethodType (List (appliedType(ByNameParamClass .typeConstructor, List (from))), to),
173
+ reportAmbiguous)
174
174
}
175
175
}
176
176
@@ -379,7 +379,7 @@ trait Typers { self: Analyzer =>
379
379
var o = owner
380
380
while (o != NoSymbol && o != sym.owner &&
381
381
! o.isLocal && ! o.hasFlag(PRIVATE ) &&
382
- ! o.privateWithin.ownerChain.contains (sym.owner))
382
+ ! o.privateWithin.hasTransOwner (sym.owner))
383
383
o = o.owner
384
384
if (o == sym.owner) addHidden(sym)
385
385
} else if (sym.owner.isTerm && ! sym.isTypeParameterOrSkolem) {
@@ -548,7 +548,7 @@ trait Typers { self: Analyzer =>
548
548
549
549
/** The member with given name of given qualifier tree */
550
550
def member (qual : Tree , name : Name ) = qual.tpe match {
551
- case ThisType (clazz) if (context.enclClass.owner.ownerChain contains clazz) =>
551
+ case ThisType (clazz) if (context.enclClass.owner.hasTransOwner( clazz) ) =>
552
552
qual.tpe.member(name)
553
553
case _ =>
554
554
if (phase.next.erasedTypes) qual.tpe.member(name)
@@ -1248,7 +1248,7 @@ trait Typers { self: Analyzer =>
1248
1248
1249
1249
private def checkStructuralCondition (refinement : Symbol , vparam : ValDef ) {
1250
1250
val tp = vparam.symbol.tpe
1251
- if (tp.typeSymbol.isAbstractType && ! (tp.typeSymbol.ownerChain contains refinement))
1251
+ if (tp.typeSymbol.isAbstractType && ! (tp.typeSymbol.hasTransOwner( refinement) ))
1252
1252
error(vparam.tpt.pos," Parameter type in structural refinement may not refer to abstract type defined outside that same refinement" )
1253
1253
}
1254
1254
@@ -3148,29 +3148,45 @@ trait Typers { self: Analyzer =>
3148
3148
* to <code>pt</code>, EmptyTree otherwise.
3149
3149
* @pre <code>info.tpe</code> does not contain an error
3150
3150
*/
3151
- private def typedImplicit (pos : Position , info : ImplicitInfo , pt : Type , isLocal : Boolean ): Tree = {
3151
+ private def typedImplicit (pos : Position , info : ImplicitInfo , pt0 : Type , pt : Type , isLocal : Boolean ): Tree = {
3152
3152
def isStable (tp : Type ): Boolean = tp match {
3153
3153
case TypeRef (pre, sym, _) => sym.isPackageClass || sym.isModuleClass && isStable(pre)
3154
3154
case _ => tp.isStable
3155
3155
}
3156
+ // println("typed impl for "+pt+"? "+info.name+":"+info.tpe+(isPlausiblyCompatible(info.tpe, pt))+isCompatible(depoly(info.tpe), pt)+isStable(info.pre))
3156
3157
if (isPlausiblyCompatible(info.tpe, pt) && isCompatible(depoly(info.tpe), pt) && isStable(info.pre)) {
3157
3158
val tree = atPos(pos) {
3158
3159
if (info.pre == NoPrefix /* isLocal*/ ) Ident (info.name)
3159
3160
else Select (gen.mkAttributedQualifier(info.pre), info.name)
3160
3161
}
3162
+ // println("typed impl?? "+info.name+":"+info.tpe+" ==> "+tree+" with "+pt)
3161
3163
def fail (reason : String , sym1 : Symbol , sym2 : Symbol ): Tree = {
3162
3164
if (settings.debug.value)
3163
- log (tree+ " is not a valid implicit value because:\n " + reason + sym1+ " " + sym2)
3165
+ println (tree+ " is not a valid implicit value because:\n " + reason + sym1+ " " + sym2)
3164
3166
EmptyTree
3165
3167
}
3166
3168
try {
3167
- // if (!isLocal) tree setSymbol info.sym
3168
- val tree1 = typed1(tree, EXPRmode , pt)
3169
- // if (settings.debug.value) log("typed implicit "+tree1+":"+tree1.tpe+", pt = "+pt)
3170
- val tree2 = adapt(tree1, EXPRmode , pt)
3171
- // if (settings.debug.value) log("adapted implicit "+tree1.symbol+":"+tree2.tpe+" to "+pt)
3169
+ // if (!isLocal) tree setSymbol info.sym
3170
+ val isView = (pt0 ne pt)
3171
+ val tree1 =
3172
+ if (isView)
3173
+ typed1(Apply (tree, List (Ident (" <argument>" ) setType pt0.paramTypes.head)), EXPRmode , pt0.resultType)
3174
+ else
3175
+ typed1(tree, EXPRmode , pt)
3176
+ // if (settings.debug.value) println("typed implicit "+tree1+":"+tree1.tpe+", pt = "+pt)
3177
+ val tree2 = if (isView) (tree1 : @ unchecked) match { case Apply (fun, _) => fun }
3178
+ else adapt(tree1, EXPRmode , pt)
3179
+ // if (settings.debug.value) println("adapted implicit "+tree1.symbol+":"+tree2.tpe+" to "+pt)("adapted implicit "+tree1.symbol+":"+tree2.tpe+" to "+pt)
3180
+ def hasMatchingSymbol (tree : Tree ): Boolean = (tree.symbol == info.sym) || {
3181
+ tree match {
3182
+ case Apply (fun, _) => hasMatchingSymbol(fun)
3183
+ case TypeApply (fun, _) => hasMatchingSymbol(fun)
3184
+ case Select (pre, name) => name == nme.apply && pre.symbol == info.sym
3185
+ case _ => false
3186
+ }
3187
+ }
3172
3188
if (tree2.tpe.isError) EmptyTree
3173
- else if (info.sym == tree1.symbol ) tree2
3189
+ else if (hasMatchingSymbol( tree1) ) tree2
3174
3190
else fail(" syms differ: " , tree1.symbol, info.sym)
3175
3191
} catch {
3176
3192
case ex : TypeError => fail(ex.getMessage(), NoSymbol , NoSymbol )
@@ -3181,15 +3197,17 @@ trait Typers { self: Analyzer =>
3181
3197
/** Infer implicit argument or view.
3182
3198
*
3183
3199
* @param pos position for error reporting
3184
- * @param pt the expected type of the implicit
3200
+ * @param pt0 the expected type of the implicit
3185
3201
* @param isView are we searching for a view? (this affects the error message)
3186
3202
* @param reportAmbiguous should ambiguous errors be reported?
3187
3203
* False iff we search for a view to find out
3188
3204
* whether one type is coercible to another
3189
3205
* @return ...
3190
3206
* @see <code>isCoercible</code>
3191
3207
*/
3192
- private def inferImplicit (pos : Position , pt : Type , isView : Boolean , reportAmbiguous : Boolean ): Tree = {
3208
+ private def inferImplicit (pos : Position , pt0 : Type , reportAmbiguous : Boolean ): Tree = {
3209
+ val pt = normalize(pt0)
3210
+ val isView = pt0.isInstanceOf [MethodType ]
3193
3211
3194
3212
if (util.Statistics .enabled) implcnt = implcnt + 1
3195
3213
val startTime = if (util.Statistics .enabled) currentTime else 0l
@@ -3239,7 +3257,7 @@ trait Typers { self: Analyzer =>
3239
3257
! containsError(info.tpe) &&
3240
3258
! (isLocal && shadowed.contains(info.name)) &&
3241
3259
(! isView || info.sym != Predef_identity ) &&
3242
- tc.typedImplicit(pos, info, pt, isLocal) != EmptyTree
3260
+ tc.typedImplicit(pos, info, pt0, pt, isLocal) != EmptyTree
3243
3261
def applicableInfos (is : List [ImplicitInfo ]) = {
3244
3262
val result = is filter isApplicable
3245
3263
if (isLocal)
@@ -3259,7 +3277,7 @@ trait Typers { self: Analyzer =>
3259
3277
" yet alternative definition " ,
3260
3278
" is defined in a subclass.\n Both definitions " )
3261
3279
}
3262
- tc.typedImplicit(pos, best, pt, isLocal)
3280
+ tc.typedImplicit(pos, best, pt0, pt, isLocal)
3263
3281
}
3264
3282
}
3265
3283
@@ -3305,7 +3323,7 @@ trait Typers { self: Analyzer =>
3305
3323
def applyImplicitArgs (tree : Tree ): Tree = tree.tpe match {
3306
3324
case MethodType (formals, _) =>
3307
3325
def implicitArg (pt : Type ) = {
3308
- val arg = inferImplicit(tree.pos, pt, false , true )
3326
+ val arg = inferImplicit(tree.pos, pt, true )
3309
3327
if (arg != EmptyTree ) arg
3310
3328
else errorTree(tree, " no implicit argument matching parameter type " + pt+ " was found." )
3311
3329
}
0 commit comments