summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2009-09-11 10:34:02 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2009-09-11 10:34:02 +0000
commit57ed4ca11459b48f2310c81beef1d31476494d25 (patch)
treef310b1456553557c67a6baae9b7d095436a6a144 /src
parent10cf73815b04d3d3d214adc1d5176daa81916e8f (diff)
downloadscala-57ed4ca11459b48f2310c81beef1d31476494d25.tar.gz
scala-57ed4ca11459b48f2310c81beef1d31476494d25.tar.bz2
scala-57ed4ca11459b48f2310c81beef1d31476494d25.zip
Fixed #2201 (slight rewrite of paulp's patch at...
Fixed #2201 (slight rewrite of paulp's patch at http://github.com/paulp/scala/commit/24419959b4d6c93716c216bbf276948a830 4b4e6) ImplicitSearch::cacheResult now clones symbols that represent bound variables (more specifically, parameters of anonymous functions that are used as implicit values) to ensure that different bound variables are represented by different symbols (otherwise lambda lifting gets confused). updated check file for bug692: error-reporting got more complete because TypeRef::transform has been relaxed slightly
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala24
2 files changed, 27 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 707137dd78..5705399428 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -1410,15 +1410,11 @@ trait Types {
sym.isModuleClass || sym == NothingClass || isValueClass(sym) || super.isNotNull
// @M: propagate actual type params (args) to `tp', by replacing formal type parameters with actual ones
+ // if tp is higher kinded, the "actual" type arguments are types that simply reference the corresponding type parameters (unbound type variables)
def transform(tp: Type): Type = {
- val args = typeArgsOrDummies
- if (args.length == sym.typeParams.length)
- tp.asSeenFrom(pre, sym.owner).instantiateTypeParams(sym.typeParams, args)
- else {
- assert(sym.typeParams.isEmpty || (args exists (_.isError)) || isRaw(sym, args)/*#2266/2305*/, tp)
- tp
- }
- // @M TODO maybe we shouldn't instantiate type params if isHigherKinded -- probably needed for partial type application though
+ val res = tp.asSeenFrom(pre, sym.owner)
+ if (sym.typeParams.isEmpty || (args exists (_.isError)) || isRaw(sym, args)/*#2266/2305*/) res
+ else res.instantiateTypeParams(sym.typeParams, typeArgsOrDummies)
}
//@M! use appliedType on the polytype that represents the bounds (or if aliastype, the rhs)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 7ebaa27872..96670ab131 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -671,6 +671,28 @@ self: Analyzer =>
}
}
+ /** Construct a fresh symbol tree for an implicit parameter
+ because of caching, must clone symbols that represent bound variables,
+ or we will end up with different bound variables that are represented by the same symbol */
+ def freshenFunctionParameters(tree : Tree) : Tree = new Transformer {
+ currentOwner = context.owner
+ override val treeCopy = new LazyTreeCopier
+ override def transform(tr : Tree) = super.transform(tr match {
+ case Function(vparams, body) => {
+ // New tree
+ val sym = tr.symbol cloneSymbol currentOwner
+ val res = tr.duplicate setSymbol sym
+ // New parameter symbols
+ var oldsyms = vparams map (_.symbol)
+ var newsyms = cloneSymbols(oldsyms, sym)
+ // Fix all symbols
+ new TreeSymSubstituter(oldsyms, newsyms) traverse res
+ res
+ }
+ case x => x
+ })
+ } transform tree
+
/** Return cached search result if found. Otherwise update cache
* but keep within sizeLimit entries
*/
@@ -679,7 +701,7 @@ self: Analyzer =>
hits += 1
if (sr == SearchFailure) sr
else {
- val result = new SearchResult(sr.tree.duplicate, sr.subst)
+ val result = new SearchResult(freshenFunctionParameters(sr.tree.duplicate), sr.subst) // #2201: generate fresh symbols for parameters
for (t <- result.tree) t.setPos(tree.pos.focus)
result
}