From 60aced6ae6f75748bd7d4cb768fc4f2f3f7ef8da Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 19 Nov 2007 17:53:49 +0000 Subject: fixed #231. --- src/compiler/scala/tools/nsc/symtab/Types.scala | 4 +- .../scala/tools/nsc/transform/UnCurry.scala | 74 ++++++++++++---------- .../tools/nsc/typechecker/SuperAccessors.scala | 8 ++- 3 files changed, 50 insertions(+), 36 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 0754313be3..112f419bcd 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -1324,7 +1324,7 @@ trait Types { val args = argsMaybeDummy if (args.length == sym.typeParams.length) tp.asSeenFrom(pre, sym.owner).instantiateTypeParams(sym.typeParams, argsMaybeDummy) - else { assert(args exists (_.isError)); tp } + else { assert(sym.typeParams.isEmpty || (args exists (_.isError)), tp); tp } // @M TODO maybe we shouldn't instantiate type params if isHigherKinded -- probably needed for partial type application though } @@ -3760,6 +3760,8 @@ A type's typeSymbol should never be inspected directly. } catch { case ex: MalformedType => None } + case _ => + assert(false, tps); None } /** Make symbol `sym' a member of scope `tp.decls' diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 4133a914b0..a013c4ea04 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -49,43 +49,49 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { private def expandAlias(tp: Type): Type = if (!tp.isHigherKinded) tp.normalize else tp private val uncurry: TypeMap = new TypeMap { - def apply(tp0: Type): Type = {val tp=expandAlias(tp0); tp match { - case MethodType(formals, MethodType(formals1, restpe)) => - apply(MethodType(formals ::: formals1, restpe)) - case MethodType(formals, ExistentialType(tparams, restpe @ MethodType(_, _))) => - assert(false, "unexpected curried method types with intervening exitential") - tp0 - case mt: ImplicitMethodType => - apply(MethodType(mt.paramTypes, mt.resultType)) - case PolyType(List(), restpe) => - apply(MethodType(List(), restpe)) - case PolyType(tparams, restpe) => - PolyType(tparams, apply(MethodType(List(), restpe))) - /* - case TypeRef(pre, sym, List(arg1, arg2)) if (arg1.typeSymbol == ByNameParamClass) => - assert(sym == FunctionClass(1)) - apply(typeRef(pre, definitions.ByNameFunctionClass, List(expandAlias(arg1.typeArgs(0)), arg2))) - */ - case TypeRef(pre, sym, List(arg)) if (sym == ByNameParamClass) => - apply(functionType(List(), arg)) - case TypeRef(pre, sym, args) if (sym == RepeatedParamClass) => - apply(rawTypeRef(pre, SeqClass, args)) - case _ => - expandAlias(mapOver(tp)) - }} + def apply(tp0: Type): Type = { + val tp = expandAlias(tp0) + tp match { + case MethodType(formals, MethodType(formals1, restpe)) => + apply(MethodType(formals ::: formals1, restpe)) + case MethodType(formals, ExistentialType(tparams, restpe @ MethodType(_, _))) => + assert(false, "unexpected curried method types with intervening exitential") + tp0 + case mt: ImplicitMethodType => + apply(MethodType(mt.paramTypes, mt.resultType)) + case PolyType(List(), restpe) => + apply(MethodType(List(), restpe)) + case PolyType(tparams, restpe) => + PolyType(tparams, apply(MethodType(List(), restpe))) + /* + case TypeRef(pre, sym, List(arg1, arg2)) if (arg1.typeSymbol == ByNameParamClass) => + assert(sym == FunctionClass(1)) + apply(typeRef(pre, definitions.ByNameFunctionClass, List(expandAlias(arg1.typeArgs(0)), arg2))) + */ + case TypeRef(pre, sym, List(arg)) if (sym == ByNameParamClass) => + apply(functionType(List(), arg)) + case TypeRef(pre, sym, args) if (sym == RepeatedParamClass) => + apply(rawTypeRef(pre, SeqClass, args)) + case _ => + expandAlias(mapOver(tp)) + } + } } private val uncurryType = new TypeMap { - def apply(tp0: Type): Type = {val tp=expandAlias(tp0); tp match { - case ClassInfoType(parents, decls, clazz) => - val parents1 = List.mapConserve(parents)(uncurry) - if (parents1 eq parents) tp - else ClassInfoType(parents1, decls, clazz) // @MAT normalize in decls?? - case PolyType(_, _) => - mapOver(tp) - case _ => - tp - }} + def apply(tp0: Type): Type = { + val tp = expandAlias(tp0) + tp match { + case ClassInfoType(parents, decls, clazz) => + val parents1 = List.mapConserve(parents)(uncurry) + if (parents1 eq parents) tp + else ClassInfoType(parents1, decls, clazz) // @MAT normalize in decls?? + case PolyType(_, _) => + mapOver(tp) + case _ => + tp + } + } } /** - return symbol's transformed type, diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index ae3a604c63..c8691d11a8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -151,7 +151,13 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT clazz.newMethod(tree.pos, supername) .setFlag(SUPERACCESSOR | PRIVATE) .setAlias(sym) - superAcc.setInfo(clazz.thisType.memberType(sym).cloneInfo(superAcc)) + var superAccTpe = clazz.thisType.memberType(sym) + if (sym.isModule && !sym.isMethod) { + // the super accessor always needs to be a method. See #231 + superAccTpe = PolyType(List(), superAccTpe) + } + superAcc.setInfo(superAccTpe.cloneInfo(superAcc)) + //println("creating super acc "+superAcc+":"+superAcc.tpe)//DEBUG clazz.info.decls enter superAcc; accDefBuf(clazz) += typed(DefDef(superAcc, vparamss => EmptyTree)) } -- cgit v1.2.3