Skip to content
This repository
Browse code

SI-1803, plus documentation and cleanups in Namers, mainly in typeSig

- when typing (and naming) a ValDef, tpt and rhs are now type checked
in the same context (the inner / ValDef context). this does not change
any behavior, but is more uniform (same as for DefDef). martin told me
(offline) that this change is desirable if it doesn't break anything.
(it doesn't).

- typeSig is now more uniform with a separate method for each case
(methodSig, valDefSig, etc). methodSig was cleaned up (no more variables)
and documented. the type returned by methodSig no longer contains /
refers to type skolems, but to the actual type parameters (so we don't
need to replace the skolems lateron).

- documentation on constructor contexts, type skolems

- more tests for SI-5543
  • Loading branch information...
commit b74c33eb860622e3630949ee0eeac9c15e8df166 1 parent a06d31f
Lukas Rytz lrytz authored
12 src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -342,6 +342,16 @@ trait Contexts { self: Analyzer =>
342 342 c
343 343 }
344 344
  345 + /**
  346 + * A context for typing constructor parameter ValDefs, super or self invocation arguments and default getters
  347 + * of constructors. These expressions need to be type checked in a scope outside the class, cf. spec 5.3.1.
  348 + *
  349 + * This method is called by namer / typer where `this` is the context for the constructor DefDef. The
  350 + * owner of the resulting (new) context is the outer context for the Template, i.e. the context for the
  351 + * ClassDef. This means that class type parameters will be in scope. The value parameters of the current
  352 + * constructor are also entered into the new constructor scope. Members of the class however will not be
  353 + * accessible.
  354 + */
345 355 def makeConstructorContext = {
346 356 var baseContext = enclClass.outer
347 357 while (baseContext.tree.isInstanceOf[Template])
@@ -361,6 +371,8 @@ trait Contexts { self: Analyzer =>
361 371 enterLocalElems(c.scope.elems)
362 372 }
363 373 }
  374 + // Enter the scope elements of this (the scope for the constructor DefDef) into the new constructor scope.
  375 + // Concretely, this will enter the value parameters of constructor.
364 376 enterElems(this)
365 377 argContext
366 378 }
5 src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -235,8 +235,8 @@ trait MethodSynthesis {
235 235 context.unit.synthetics get meth match {
236 236 case Some(mdef) =>
237 237 context.unit.synthetics -= meth
238   - meth setAnnotations deriveAnnotations(annotations, MethodTargetClass, false)
239   - cd.symbol setAnnotations deriveAnnotations(annotations, ClassTargetClass, true)
  238 + meth setAnnotations deriveAnnotations(annotations, MethodTargetClass, keepClean = false)
  239 + cd.symbol setAnnotations deriveAnnotations(annotations, ClassTargetClass, keepClean = true)
240 240 List(cd, mdef)
241 241 case _ =>
242 242 // Shouldn't happen, but let's give ourselves a reasonable error when it does
@@ -329,6 +329,7 @@ trait MethodSynthesis {
329 329 */
330 330 def category: Symbol
331 331
  332 + /* Explicit isSetter required for bean setters (beanSetterSym.isSetter is false) */
332 333 final def completer(sym: Symbol) = namerOf(sym).accessorTypeCompleter(tree, isSetter)
333 334 final def fieldSelection = Select(This(enclClass), basisSym)
334 335 final def derivedMods: Modifiers = mods & flagsMask | flagsExtra mapAnnotations (_ => Nil)
490 src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -65,7 +65,18 @@ trait Namers extends MethodSynthesis {
65 65 case ModuleDef(_, _, _) => tree.symbol.moduleClass
66 66 case _ => tree.symbol
67 67 }
68   - newNamer(context.makeNewScope(tree, sym))
  68 + def isConstrParam(vd: ValDef) = {
  69 + (sym hasFlag PARAM | PRESUPER) &&
  70 + !vd.mods.isJavaDefined &&
  71 + sym.owner.isConstructor
  72 + }
  73 + val ownerCtx = tree match {
  74 + case vd: ValDef if isConstrParam(vd) =>
  75 + context.makeConstructorContext
  76 + case _ =>
  77 + context
  78 + }
  79 + newNamer(ownerCtx.makeNewScope(tree, sym))
69 80 }
70 81 def createInnerNamer() = {
71 82 newNamer(context.make(context.tree, owner, newScope))
@@ -423,6 +434,7 @@ trait Namers extends MethodSynthesis {
423 434 def enterSyms(trees: List[Tree]): Namer = {
424 435 trees.foldLeft(this: Namer) { (namer, t) =>
425 436 val ctx = namer enterSym t
  437 + // for Import trees, enterSym returns a changed context, so we need a new namer
426 438 if (ctx eq namer.context) namer
427 439 else newNamer(ctx)
428 440 }
@@ -521,20 +533,19 @@ trait Namers extends MethodSynthesis {
521 533 noDuplicates(selectors map (_.rename), AppearsTwice)
522 534 }
523 535
524   - def enterCopyMethod(copyDefDef: Tree, tparams: List[TypeDef]): Symbol = {
525   - val sym = copyDefDef.symbol
526   - val lazyType = completerOf(copyDefDef, tparams)
  536 + def enterCopyMethod(copyDef: DefDef): Symbol = {
  537 + val sym = copyDef.symbol
  538 + val lazyType = completerOf(copyDef)
527 539
528 540 /** Assign the types of the class parameters to the parameters of the
529 541 * copy method. See comment in `Unapplies.caseClassCopyMeth` */
530 542 def assignParamTypes() {
531 543 val clazz = sym.owner
532 544 val constructorType = clazz.primaryConstructor.tpe
533   - val subst = new SubstSymMap(clazz.typeParams, tparams map (_.symbol))
  545 + val subst = new SubstSymMap(clazz.typeParams, copyDef.tparams map (_.symbol))
534 546 val classParamss = constructorType.paramss
535   - val DefDef(_, _, _, copyParamss, _, _) = copyDefDef
536 547
537   - map2(copyParamss, classParamss)((copyParams, classParams) =>
  548 + map2(copyDef.vparamss, classParamss)((copyParams, classParams) =>
538 549 map2(copyParams, classParams)((copyP, classP) =>
539 550 copyP.tpt setType subst(classP.tpe)
540 551 )
@@ -542,24 +553,28 @@ trait Namers extends MethodSynthesis {
542 553 }
543 554
544 555 sym setInfo {
545   - mkTypeCompleter(copyDefDef) { sym =>
  556 + mkTypeCompleter(copyDef) { sym =>
546 557 assignParamTypes()
547 558 lazyType complete sym
548 559 }
549 560 }
550 561 }
551   - def completerOf(tree: Tree): TypeCompleter = completerOf(tree, treeInfo.typeParameters(tree))
552   - def completerOf(tree: Tree, tparams: List[TypeDef]): TypeCompleter = {
  562 +
  563 + def completerOf(tree: Tree): TypeCompleter = {
553 564 val mono = namerOf(tree.symbol) monoTypeCompleter tree
  565 + val tparams = treeInfo.typeParameters(tree)
554 566 if (tparams.isEmpty) mono
555 567 else {
556   - //@M! TypeDef's type params are handled differently
557   - //@M e.g., in [A[x <: B], B], A and B are entered first as both are in scope in the definition of x
558   - //@M x is only in scope in `A[x <: B]'
  568 + /* @M! TypeDef's type params are handled differently, e.g., in `type T[A[x <: B], B]`, A and B are entered
  569 + * first as both are in scope in the definition of x. x is only in scope in `A[x <: B]`.
  570 + * No symbols are created for the abstract type's params at this point, i.e. the following assertion holds:
  571 + * !tree.symbol.isAbstractType || { tparams.forall(_.symbol == NoSymbol)
  572 + * (tested with the above example, `trait C { type T[A[X <: B], B] }`). See also comment in PolyTypeCompleter.
  573 + */
559 574 if (!tree.symbol.isAbstractType) //@M TODO: change to isTypeMember ?
560 575 createNamer(tree) enterSyms tparams
561 576
562   - new PolyTypeCompleter(tparams, mono, tree, context) //@M
  577 + new PolyTypeCompleter(tparams, mono, context) //@M
563 578 }
564 579 }
565 580
@@ -621,9 +636,9 @@ trait Namers extends MethodSynthesis {
621 636 val sym = assignAndEnterSymbol(tree) setFlag bridgeFlag
622 637
623 638 if (name == nme.copy && sym.isSynthetic)
624   - enterCopyMethod(tree, tparams)
  639 + enterCopyMethod(tree)
625 640 else
626   - sym setInfo completerOf(tree, tparams)
  641 + sym setInfo completerOf(tree)
627 642 }
628 643
629 644 def enterClassDef(tree: ClassDef) {
@@ -736,7 +751,8 @@ trait Namers extends MethodSynthesis {
736 751 }
737 752 }
738 753
739   - def accessorTypeCompleter(tree: ValDef, isSetter: Boolean = false) = mkTypeCompleter(tree) { sym =>
  754 + /* Explicit isSetter required for bean setters (beanSetterSym.isSetter is false) */
  755 + def accessorTypeCompleter(tree: ValDef, isSetter: Boolean) = mkTypeCompleter(tree) { sym =>
740 756 logAndValidate(sym) {
741 757 sym setInfo {
742 758 if (isSetter)
@@ -805,17 +821,12 @@ trait Namers extends MethodSynthesis {
805 821 * assigns the type to the tpt's node. Returns the type.
806 822 */
807 823 private def assignTypeToTree(tree: ValOrDefDef, defnTyper: Typer, pt: Type): Type = {
808   - // compute result type from rhs
809   - val typedBody =
  824 + val rhsTpe =
810 825 if (tree.symbol.isTermMacro) defnTyper.computeMacroDefType(tree, pt)
811 826 else defnTyper.computeType(tree.rhs, pt)
812 827
813   - val typedDefn = widenIfNecessary(tree.symbol, typedBody, pt)
814   - assignTypeToTree(tree, typedDefn)
815   - }
816   -
817   - private def assignTypeToTree(tree: ValOrDefDef, tpe: Type): Type = {
818   - tree.tpt defineType tpe setPos tree.pos.focus
  828 + val defnTpe = widenIfNecessary(tree.symbol, rhsTpe, pt)
  829 + tree.tpt defineType defnTpe setPos tree.pos.focus
819 830 tree.tpt.tpe
820 831 }
821 832
@@ -895,155 +906,245 @@ trait Namers extends MethodSynthesis {
895 906 ClassInfoType(parents, decls, clazz)
896 907 }
897 908
898   - private def classSig(tparams: List[TypeDef], impl: Template): Type = {
  909 + private def classSig(cdef: ClassDef): Type = {
  910 + val clazz = cdef.symbol
  911 + val ClassDef(_, _, tparams, impl) = cdef
899 912 val tparams0 = typer.reenterTypeParams(tparams)
900 913 val resultType = templateSig(impl)
901 914
902   - GenPolyType(tparams0, resultType)
  915 + val res = GenPolyType(tparams0, resultType)
  916 +
  917 + // Already assign the type to the class symbol (monoTypeCompleter will do it again).
  918 + // Allows isDerivedValueClass to look at the info.
  919 + clazz setInfo res
  920 + if (clazz.isDerivedValueClass) {
  921 + log("Ensuring companion for derived value class " + cdef.name + " at " + cdef.pos.show)
  922 + clazz setFlag FINAL
  923 + // Don't force the owner's info lest we create cycles as in SI-6357.
  924 + enclosingNamerWithScope(clazz.owner.rawInfo.decls).ensureCompanionObject(cdef)
  925 + }
  926 + res
903 927 }
904 928
905   - private def methodSig(ddef: DefDef, mods: Modifiers, tparams: List[TypeDef],
906   - vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): Type = {
907   - val meth = owner
908   - val clazz = meth.owner
909   - // enters the skolemized version into scope, returns the deSkolemized symbols
910   - val tparamSyms = typer.reenterTypeParams(tparams)
911   - // since the skolemized tparams are in scope, the TypeRefs in vparamSymss refer to skolemized tparams
912   - var vparamSymss = enterValueParams(vparamss)
  929 + private def moduleSig(mdef: ModuleDef): Type = {
  930 + val moduleSym = mdef.symbol
  931 + // The info of both the module and the moduleClass symbols need to be assigned. monoTypeCompleter assigns
  932 + // the result of typeSig to the module symbol. The module class info is assigned here as a side-effect.
  933 + val result = templateSig(mdef.impl)
  934 + // Assign the moduleClass info (templateSig returns a ClassInfoType)
  935 + val clazz = moduleSym.moduleClass
  936 + clazz setInfo result
  937 + // clazz.tpe returns a `ModuleTypeRef(clazz)`, a typeRef that links to the module class `clazz`
  938 + // (clazz.info would the ClassInfoType, which is not what should be assigned to the module symbol)
  939 + clazz.tpe
  940 + }
  941 +
  942 + /**
  943 + * The method type for `ddef`.
  944 + *
  945 + * If a PolyType(tparams, restp) is returned, `tparams` are the external symbols (not type skolems),
  946 + * i.e. instances of AbstractTypeSymbol. All references in `restp` to the type parameters are TypeRefs
  947 + * to these non-skolems.
  948 + *
  949 + * For type-checking the rhs (in case the result type is inferred), the type skolems of the type parameters
  950 + * are entered in scope. Equally, the parameter symbols entered into scope have types which refer to those
  951 + * skolems: when type-checking the rhs, references to parameters need to have types that refer to the skolems.
  952 + * In summary, typing an rhs happens with respect to the skolems.
  953 + *
  954 + * This means that the method's result type computed by the typer refers to skolems. In order to put it
  955 + * into the method type (the result of methodSig), typeRefs to skolems have to be replaced by references
  956 + * to the non-skolems.
  957 + */
  958 + private def methodSig(ddef: DefDef): Type = {
913 959
914 960 // DEPMETTODO: do we need to skolemize value parameter symbols?
915   - if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) {
916   - tpt defineType context.enclClass.owner.tpe
917   - tpt setPos meth.pos.focus
918   - }
919   - var resultPt = if (tpt.isEmpty) WildcardType else typer.typedType(tpt).tpe
920   - val site = clazz.thisType
921 961
922   - /** Called for all value parameter lists, right to left
923   - * @param vparams the symbols of one parameter list
924   - * @param restpe the result type (possibly a MethodType)
  962 + val DefDef(_, _, tparams, vparamss, tpt, _) = ddef
  963 +
  964 + val meth = owner
  965 + val methOwner = meth.owner
  966 + val site = methOwner.thisType
  967 +
  968 + /* tparams already have symbols (created in enterDefDef/completerOf), namely the skolemized ones (created
  969 + * by the PolyTypeCompleter constructor, and assigned to tparams). reenterTypeParams enters the type skolems
  970 + * into scope and returns the non-skolems.
925 971 */
926   - def makeMethodType(vparams: List[Symbol], restpe: Type) = {
927   - // TODODEPMET: check that we actually don't need to do anything here
928   - // new dependent method types: probably OK already, since 'enterValueParams' above
929   - // enters them in scope, and all have a lazy type. so they may depend on other params. but: need to
930   - // check that params only depend on ones in earlier sections, not the same. (done by checkDependencies,
931   - // so re-use / adapt that)
932   - if (owner.isJavaDefined)
933   - // TODODEPMET necessary?? new dependent types: replace symbols in restpe with the ones in vparams
934   - JavaMethodType(vparams map (p => p setInfo objToAny(p.tpe)), restpe)
935   - else
936   - MethodType(vparams, restpe)
937   - }
  972 + val tparamSyms = typer.reenterTypeParams(tparams)
  973 +
  974 + val tparamSkolems = tparams.map(_.symbol)
  975 +
  976 + /* since the skolemized tparams are in scope, the TypeRefs in types of vparamSymss refer to the type skolems
  977 + * note that for parameters with missing types, `methodSig` reassigns types of these symbols (the parameter
  978 + * types from the overridden method).
  979 + */
  980 + var vparamSymss = enterValueParams(vparamss)
  981 +
938 982
  983 + /**
  984 + * Creates a method type using tparamSyms and vparamsSymss as argument symbols and `respte` as result type.
  985 + * All typeRefs to type skolems are replaced by references to the corresponding non-skolem type parameter,
  986 + * so the resulting type is a valid external method type, it does not contain (references to) skolems.
  987 + */
939 988 def thisMethodType(restpe: Type) = {
940 989 val checkDependencies = new DependentTypeChecker(context)(this)
941 990 checkDependencies check vparamSymss
942 991 // DEPMETTODO: check not needed when they become on by default
943 992 checkDependencies(restpe)
944 993
945   - GenPolyType(
  994 + val makeMethodType = (vparams: List[Symbol], restpe: Type) => {
  995 + // TODODEPMET: check that we actually don't need to do anything here
  996 + // new dependent method types: probably OK already, since 'enterValueParams' above
  997 + // enters them in scope, and all have a lazy type. so they may depend on other params. but: need to
  998 + // check that params only depend on ones in earlier sections, not the same. (done by checkDependencies,
  999 + // so re-use / adapt that)
  1000 + if (meth.isJavaDefined)
  1001 + // TODODEPMET necessary?? new dependent types: replace symbols in restpe with the ones in vparams
  1002 + JavaMethodType(vparams map (p => p setInfo objToAny(p.tpe)), restpe)
  1003 + else
  1004 + MethodType(vparams, restpe)
  1005 + }
  1006 +
  1007 +
  1008 + val res = GenPolyType(
946 1009 tparamSyms, // deSkolemized symbols -- TODO: check that their infos don't refer to method args?
947 1010 if (vparamSymss.isEmpty) NullaryMethodType(restpe)
948 1011 // vparamss refer (if they do) to skolemized tparams
949 1012 else (vparamSymss :\ restpe) (makeMethodType)
950 1013 )
  1014 + res.substSym(tparamSkolems, tparamSyms)
951 1015 }
952 1016
953   - def transformedResult =
954   - thisMethodType(resultPt).substSym(tparams map (_.symbol), tparamSyms)
  1017 + /**
  1018 + * Creates a schematic method type which has WildcardTypes for non specified
  1019 + * return or parameter types. For instance, in `def f[T](a: T, b) = ...`, the
  1020 + * type schema is
  1021 + *
  1022 + * PolyType(T, MethodType(List(a: T, b: WildcardType), WildcardType))
  1023 + *
  1024 + * where T are non-skolems.
  1025 + */
  1026 + def methodTypeSchema(resTp: Type) = {
  1027 + // for all params without type set WildcaradType
  1028 + mforeach(vparamss)(v => if (v.tpt.isEmpty) v.symbol setInfo WildcardType)
  1029 + thisMethodType(resTp)
  1030 + }
955 1031
956   - // luc: added .substSym from skolemized to deSkolemized
957   - // site.memberType(sym): PolyType(tparams, MethodType(..., ...))
958   - // ==> all references to tparams are deSkolemized
959   - // thisMethodType: tparams in PolyType are deSkolemized, the references in the MethodTypes are skolemized.
960   - // ==> the two didn't match
961   - //
962   - // for instance, B.foo would not override A.foo, and the default on parameter b would not be inherited
963   - // class A { def foo[T](a: T)(b: T = a) = a }
964   - // class B extends A { override def foo[U](a: U)(b: U) = b }
965   - def overriddenSymbol =
966   - intersectionType(clazz.info.parents).nonPrivateMember(meth.name).filter { sym =>
967   - sym != NoSymbol && (site.memberType(sym) matches transformedResult)
  1032 + def overriddenSymbol(resTp: Type) = {
  1033 + intersectionType(methOwner.info.parents).nonPrivateMember(meth.name).filter { sym =>
  1034 + sym != NoSymbol && (site.memberType(sym) matches methodTypeSchema(resTp))
968 1035 }
969   - // TODO: see whether this or something similar would work instead.
970   - //
  1036 + }
  1037 + // TODO: see whether this or something similar would work instead:
971 1038 // def overriddenSymbol = meth.nextOverriddenSymbol
972 1039
973   - // fill in result type and parameter types from overridden symbol if there is a unique one.
974   - if (clazz.isClass && (tpt.isEmpty || mexists(vparamss)(_.tpt.isEmpty))) {
975   - // try to complete from matching definition in base type
976   - mforeach(vparamss)(v => if (v.tpt.isEmpty) v.symbol setInfo WildcardType)
977   - val overridden = overriddenSymbol
978   - if (overridden != NoSymbol && !overridden.isOverloaded) {
979   - overridden.cookJavaRawInfo() // #3404 xform java rawtypes into existentials
980   - resultPt = site.memberType(overridden) match {
981   - case PolyType(tparams, rt) => rt.substSym(tparams, tparamSyms)
982   - case mt => mt
983   - }
984 1040
  1041 + /**
  1042 + * If `meth` doesn't have an explicit return type, extracts the return type from the method
  1043 + * overridden by `meth` (if there's an unique one). This type is lateron used as the expected
  1044 + * type for computing the type of the rhs. The resulting type references type skolems for
  1045 + * type parameters (consistent with the result of `typer.typedType(tpt).tpe`).
  1046 + *
  1047 + * As a first side effect, this method assigns a MethodType constructed using this
  1048 + * return type to `meth`. This allows omitting the result type for recursive methods.
  1049 + *
  1050 + * As another side effect, this method also assigns paramter types from the overridden
  1051 + * method to parameters of `meth` that have missing types (the parser accepts missing
  1052 + * parameter types under -Yinfer-argument-types).
  1053 + */
  1054 + def typesFromOverridden(methResTp: Type): Type = {
  1055 + val overridden = overriddenSymbol(methResTp)
  1056 + if (overridden == NoSymbol || overridden.isOverloaded) {
  1057 + methResTp
  1058 + } else {
  1059 + overridden.cookJavaRawInfo() // #3404 xform java rawtypes into existentials
  1060 + var overriddenTp = site.memberType(overridden) match {
  1061 + case PolyType(tparams, rt) => rt.substSym(tparams, tparamSkolems)
  1062 + case mt => mt
  1063 + }
985 1064 for (vparams <- vparamss) {
986   - var pps = resultPt.params
  1065 + var overriddenParams = overriddenTp.params
987 1066 for (vparam <- vparams) {
988 1067 if (vparam.tpt.isEmpty) {
989   - val paramtpe = pps.head.tpe
990   - vparam.symbol setInfo paramtpe
991   - vparam.tpt defineType paramtpe setPos vparam.pos.focus
  1068 + val overriddenParamTp = overriddenParams.head.tpe
  1069 + // references to type parameteres in overriddenParamTp link to the type skolems, so the
  1070 + // assigned type is consistent with the other / existing parameter types in vparamSymss.
  1071 + vparam.symbol setInfo overriddenParamTp
  1072 + vparam.tpt defineType overriddenParamTp setPos vparam.pos.focus
992 1073 }
993   - pps = pps.tail
  1074 + overriddenParams = overriddenParams.tail
994 1075 }
995   - resultPt = resultPt.resultType
  1076 + overriddenTp = overriddenTp.resultType
996 1077 }
997   - resultPt match {
998   - case NullaryMethodType(rtpe) => resultPt = rtpe
999   - case MethodType(List(), rtpe) => resultPt = rtpe
  1078 +
  1079 + overriddenTp match {
  1080 + case NullaryMethodType(rtpe) => overriddenTp = rtpe
  1081 + case MethodType(List(), rtpe) => overriddenTp = rtpe
1000 1082 case _ =>
1001 1083 }
  1084 +
1002 1085 if (tpt.isEmpty) {
1003 1086 // provisionally assign `meth` a method type with inherited result type
1004 1087 // that way, we can leave out the result type even if method is recursive.
1005   - meth setInfo thisMethodType(resultPt)
  1088 + meth setInfo thisMethodType(overriddenTp)
  1089 + overriddenTp
  1090 + } else {
  1091 + methResTp
1006 1092 }
1007 1093 }
1008 1094 }
1009   - // Add a () parameter section if this overrides some method with () parameters.
1010   - if (clazz.isClass && vparamss.isEmpty && overriddenSymbol.alternatives.exists(
1011   - _.info.isInstanceOf[MethodType])) {
  1095 +
  1096 + if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) {
  1097 + tpt defineType context.enclClass.owner.tpe
  1098 + tpt setPos meth.pos.focus
  1099 + }
  1100 +
  1101 + val methResTp = if (tpt.isEmpty) WildcardType else typer.typedType(tpt).tpe
  1102 + val resTpFromOverride = if (methOwner.isClass && (tpt.isEmpty || mexists(vparamss)(_.tpt.isEmpty))) {
  1103 + typesFromOverridden(methResTp)
  1104 + } else {
  1105 + methResTp
  1106 + }
  1107 +
  1108 + // Add a () parameter section if this overrides some method with () parameters
  1109 + if (methOwner.isClass && vparamss.isEmpty &&
  1110 + overriddenSymbol(methResTp).alternatives.exists(_.info.isInstanceOf[MethodType])) {
1012 1111 vparamSymss = ListOfNil
1013 1112 }
  1113 +
  1114 + // issue an error for missing parameter types
1014 1115 mforeach(vparamss) { vparam =>
1015 1116 if (vparam.tpt.isEmpty) {
1016 1117 MissingParameterOrValTypeError(vparam)
1017 1118 vparam.tpt defineType ErrorType
1018 1119 }
1019 1120 }
1020   - addDefaultGetters(meth, vparamss, tparams, overriddenSymbol)
  1121 +
  1122 + addDefaultGetters(meth, vparamss, tparams, overriddenSymbol(methResTp))
1021 1123
1022 1124 // fast track macros, i.e. macros defined inside the compiler, are hardcoded
1023 1125 // hence we make use of that and let them have whatever right-hand side they need
1024 1126 // (either "macro ???" as they used to or just "???" to maximally simplify their compilation)
1025   - if (fastTrack contains ddef.symbol) ddef.symbol setFlag MACRO
  1127 + if (fastTrack contains meth) meth setFlag MACRO
1026 1128
1027 1129 // macro defs need to be typechecked in advance
1028 1130 // because @macroImpl annotation only gets assigned during typechecking
1029 1131 // otherwise macro defs wouldn't be able to robustly coexist with their clients
1030 1132 // because a client could be typechecked before a macro def that it uses
1031   - if (ddef.symbol.isTermMacro) {
1032   - val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol))
1033   - typer.computeMacroDefType(ddef, pt)
  1133 + if (meth.isTermMacro) {
  1134 + typer.computeMacroDefType(ddef, resTpFromOverride)
1034 1135 }
1035 1136
1036 1137 thisMethodType({
1037 1138 val rt = (
1038 1139 if (!tpt.isEmpty) {
1039   - typer.typedType(tpt).tpe
  1140 + methResTp
1040 1141 } else {
1041   - // replace deSkolemized symbols with skolemized ones
1042   - // (for resultPt computed by looking at overridden symbol, right?)
1043   - val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol))
1044   - assignTypeToTree(ddef, typer, pt)
1045   - }
1046   - )
  1142 + // return type is inferred, we don't just use resTpFromOverride. Here, C.f has type String:
  1143 + // trait T { def f: Object }; class C <: T { def f = "" }
  1144 + // using resTpFromOverride as expected type allows for the following (C.f has type A):
  1145 + // trait T { def f: A }; class C <: T { implicit def b2a(t: B): A = ???; def f = new B }
  1146 + assignTypeToTree(ddef, typer, resTpFromOverride)
  1147 + })
1047 1148 // #2382: return type of default getters are always @uncheckedVariance
1048 1149 if (meth.hasDefault)
1049 1150 rt.withAnnotation(AnnotationInfo(uncheckedVarianceClass.tpe, List(), List()))
@@ -1060,9 +1161,9 @@ trait Namers extends MethodSynthesis {
1060 1161 * flag.
1061 1162 */
1062 1163 private def addDefaultGetters(meth: Symbol, vparamss: List[List[ValDef]], tparams: List[TypeDef], overriddenSymbol: => Symbol) {
1063   - val clazz = meth.owner
  1164 + val methOwner = meth.owner
1064 1165 val isConstr = meth.isConstructor
1065   - val overridden = if (isConstr || !clazz.isClass) NoSymbol else overriddenSymbol
  1166 + val overridden = if (isConstr || !methOwner.isClass) NoSymbol else overriddenSymbol
1066 1167 val overrides = overridden != NoSymbol && !overridden.isOverloaded
1067 1168 // value parameters of the base class (whose defaults might be overridden)
1068 1169 var baseParamss = (vparamss, overridden.tpe.paramss) match {
@@ -1112,7 +1213,7 @@ trait Namers extends MethodSynthesis {
1112 1213
1113 1214 val parentNamer = if (isConstr) {
1114 1215 val (cdef, nmr) = moduleNamer.getOrElse {
1115   - val module = companionSymbolOf(clazz, context)
  1216 + val module = companionSymbolOf(methOwner, context)
1116 1217 module.initialize // call type completer (typedTemplate), adds the
1117 1218 // module's templateNamer to classAndNamerOfModule
1118 1219 module.attachments.get[ConstructorDefaultsAttachment] match {
@@ -1158,7 +1259,7 @@ trait Namers extends MethodSynthesis {
1158 1259 name, deftParams, defvParamss, defTpt, defRhs)
1159 1260 }
1160 1261 if (!isConstr)
1161   - clazz.resetFlag(INTERFACE) // there's a concrete member now
  1262 + methOwner.resetFlag(INTERFACE) // there's a concrete member now
1162 1263 val default = parentNamer.enterSyntheticSym(defaultTree)
1163 1264 if (forInteractive && default.owner.isTerm) {
1164 1265 // save the default getters as attachments in the method symbol. if compiling the
@@ -1183,15 +1284,29 @@ trait Namers extends MethodSynthesis {
1183 1284 }
1184 1285 }
1185 1286
  1287 + private def valDefSig(vdef: ValDef) = {
  1288 + val ValDef(_, _, tpt, rhs) = vdef
  1289 + if (tpt.isEmpty) {
  1290 + if (rhs.isEmpty) {
  1291 + MissingParameterOrValTypeError(tpt)
  1292 + ErrorType
  1293 + }
  1294 + else assignTypeToTree(vdef, typer, WildcardType)
  1295 + } else {
  1296 + typer.typedType(tpt).tpe
  1297 + }
  1298 + }
  1299 +
1186 1300 //@M! an abstract type definition (abstract type member/type parameter)
1187 1301 // may take type parameters, which are in scope in its bounds
1188   - private def typeDefSig(tpsym: Symbol, tparams: List[TypeDef], rhs: Tree) = {
  1302 + private def typeDefSig(tdef: TypeDef) = {
  1303 + val TypeDef(_, _, tparams, rhs) = tdef
1189 1304 // log("typeDefSig(" + tpsym + ", " + tparams + ")")
1190 1305 val tparamSyms = typer.reenterTypeParams(tparams) //@M make tparams available in scope (just for this abstypedef)
1191 1306 val tp = typer.typedType(rhs).tpe match {
1192 1307 case TypeBounds(lt, rt) if (lt.isError || rt.isError) =>
1193 1308 TypeBounds.empty
1194   - case tp @ TypeBounds(lt, rt) if (tpsym hasFlag JAVA) =>
  1309 + case tp @ TypeBounds(lt, rt) if (tdef.symbol hasFlag JAVA) =>
1195 1310 TypeBounds(lt, objToAny(rt))
1196 1311 case tp =>
1197 1312 tp
@@ -1216,6 +1331,28 @@ trait Namers extends MethodSynthesis {
1216 1331 GenPolyType(tparamSyms, tp)
1217 1332 }
1218 1333
  1334 + private def importSig(imp: Import) = {
  1335 + val Import(expr, selectors) = imp
  1336 + val expr1 = typer.typedQualifier(expr)
  1337 + typer checkStable expr1
  1338 + if (expr1.symbol != null && expr1.symbol.isRootPackage)
  1339 + RootImportError(imp)
  1340 +
  1341 + if (expr1.isErrorTyped)
  1342 + ErrorType
  1343 + else {
  1344 + val newImport = treeCopy.Import(imp, expr1, selectors).asInstanceOf[Import]
  1345 + checkSelectors(newImport)
  1346 + transformed(imp) = newImport
  1347 + // copy symbol and type attributes back into old expression
  1348 + // so that the structure builder will find it.
  1349 + expr.symbol = expr1.symbol
  1350 + expr.tpe = expr1.tpe
  1351 + ImportType(expr1)
  1352 + }
  1353 + }
  1354 +
  1355 +
1219 1356 /** Given a case class
1220 1357 * case class C[Ts] (ps: Us)
1221 1358 * Add the following methods to toScope:
@@ -1239,6 +1376,11 @@ trait Namers extends MethodSynthesis {
1239 1376 caseClassCopyMeth(cdef) foreach namer.enterSyntheticSym
1240 1377 }
1241 1378
  1379 + /**
  1380 + * TypeSig is invoked by monoTypeCompleters. It returns the type of a definition which
  1381 + * is then assigned to the corresponding symbol (typeSig itself does not need to assign
  1382 + * the type to the symbol, but it can if necessary).
  1383 + */
1242 1384 def typeSig(tree: Tree): Type = {
1243 1385 // log("typeSig " + tree)
1244 1386 /** For definitions, transform Annotation trees to AnnotationInfos, assign
@@ -1271,84 +1413,33 @@ trait Namers extends MethodSynthesis {
1271 1413 }
1272 1414
1273 1415 val sym: Symbol = tree.symbol
1274   - // @Lukas: I am not sure this is the right way to do things.
1275   - // We used to only decorate the module class with annotations, which is
1276   - // clearly wrong. Now we decorate both the class and the object.
1277   - // But maybe some annotations are only meant for one of these but not for the other?
1278   - //
1279   - // TODO: meta-annotations to indicate class vs. object.
  1416 +
  1417 + // TODO: meta-annotations to indicate where module annotations should go (module vs moduleClass)
1280 1418 annotate(sym)
1281 1419 if (sym.isModule) annotate(sym.moduleClass)
1282 1420
1283 1421 def getSig = tree match {
1284   - case cdef @ ClassDef(_, name, tparams, impl) =>
1285   - val clazz = tree.symbol
1286   - val result = createNamer(tree).classSig(tparams, impl)
1287   - clazz setInfo result
1288   - if (clazz.isDerivedValueClass) {
1289   - log("Ensuring companion for derived value class " + name + " at " + cdef.pos.show)
1290   - clazz setFlag FINAL
1291   - // Don't force the owner's info lest we create cycles as in SI-6357.
1292   - enclosingNamerWithScope(clazz.owner.rawInfo.decls).ensureCompanionObject(cdef)
1293   - }
1294   - result
1295   -
1296   - case ModuleDef(_, _, impl) =>
1297   - val clazz = sym.moduleClass
1298   - clazz setInfo createNamer(tree).templateSig(impl)
1299   - clazz.tpe
1300   -
1301   - case ddef @ DefDef(mods, _, tparams, vparamss, tpt, rhs) =>
1302   - // TODO: cleanup parameter list
1303   - createNamer(tree).methodSig(ddef, mods, tparams, vparamss, tpt, rhs)
1304   -
1305   - case vdef @ ValDef(mods, name, tpt, rhs) =>
1306   - val isBeforeSupercall = (
1307   - (sym hasFlag PARAM | PRESUPER)
1308   - && !mods.isJavaDefined
1309   - && sym.owner.isConstructor
1310   - )
1311   - val typer1 = typer.constrTyperIf(isBeforeSupercall)
1312   - if (tpt.isEmpty) {
1313   - if (rhs.isEmpty) {
1314   - MissingParameterOrValTypeError(tpt)
1315   - ErrorType
1316   - }
1317   - else assignTypeToTree(vdef, newTyper(typer1.context.make(vdef, sym)), WildcardType)
1318   - }
1319   - else typer1.typedType(tpt).tpe
1320   -
1321   - case TypeDef(_, _, tparams, rhs) =>
1322   - createNamer(tree).typeDefSig(sym, tparams, rhs) //@M!
1323   -
1324   - case Import(expr, selectors) =>
1325   - val expr1 = typer.typedQualifier(expr)
1326   - typer checkStable expr1
1327   - if (expr1.symbol != null && expr1.symbol.isRootPackage)
1328   - RootImportError(tree)
1329   -
1330   - if (expr1.isErrorTyped)
1331   - ErrorType
1332   - else {
1333   - val newImport = treeCopy.Import(tree, expr1, selectors).asInstanceOf[Import]
1334   - checkSelectors(newImport)
1335   - transformed(tree) = newImport
1336   - // copy symbol and type attributes back into old expression
1337   - // so that the structure builder will find it.
1338   - expr.symbol = expr1.symbol
1339   - expr.tpe = expr1.tpe
1340   - ImportType(expr1)
1341   - }
1342   - }
  1422 + case cdef: ClassDef =>
  1423 + createNamer(tree).classSig(cdef)
  1424 +
  1425 + case mdef: ModuleDef =>
  1426 + createNamer(tree).moduleSig(mdef)
  1427 +
  1428 + case ddef: DefDef =>
  1429 + createNamer(tree).methodSig(ddef)
1343 1430
1344   - val result =
1345   - try getSig
1346   - catch typeErrorHandler(tree, ErrorType)
  1431 + case vdef: ValDef =>
  1432 + createNamer(tree).valDefSig(vdef)
1347 1433
1348   - result match {
1349   - case PolyType(tparams @ (tp :: _), _) if tp.owner.isTerm => deskolemizeTypeParams(tparams)(result)
1350   - case _ => result
  1434 + case tdef: TypeDef =>
  1435 + createNamer(tree).typeDefSig(tdef) //@M!
  1436 +
  1437 + case imp: Import =>
  1438 + importSig(imp)
1351 1439 }
  1440 +
  1441 + try getSig
  1442 + catch typeErrorHandler(tree, ErrorType)
1352 1443 }
1353 1444
1354 1445 def includeParent(tpe: Type, parent: Symbol): Type = tpe match {
@@ -1508,14 +1599,25 @@ trait Namers extends MethodSynthesis {
1508 1599 }
1509 1600 }
1510 1601
1511   - /** A class representing a lazy type with known type parameters.
  1602 + /**
  1603 + * A class representing a lazy type with known type parameters. `ctx` is the namer context in which the
  1604 + * `owner` is defined.
  1605 + *
  1606 + * Constructing a PolyTypeCompleter for a DefDef creates type skolems for the type parameters and
  1607 + * assigns them to the `tparams` trees.
1512 1608 */
1513   - class PolyTypeCompleter(tparams: List[TypeDef], restp: TypeCompleter, owner: Tree, ctx: Context) extends LockingTypeCompleter with FlagAgnosticCompleter {
1514   - private val ownerSym = owner.symbol
1515   - override val typeParams = tparams map (_.symbol) //@M
1516   - override val tree = restp.tree
  1609 + class PolyTypeCompleter(tparams: List[TypeDef], restp: TypeCompleter, ctx: Context) extends LockingTypeCompleter with FlagAgnosticCompleter {
  1610 + // @M. If `owner` is an abstract type member, `typeParams` are all NoSymbol (see comment in `completerOf`),
  1611 + // otherwise, the non-skolemized (external) type parameter symbols
  1612 + override val typeParams = tparams map (_.symbol)
  1613 +
  1614 + /* The definition tree (poly ClassDef, poly DefDef or HK TypeDef) */
  1615 + override val tree = restp.tree
  1616 +
  1617 + private val defnSym = tree.symbol
1517 1618
1518   - if (ownerSym.isTerm) {
  1619 + if (defnSym.isTerm) {
  1620 + // for polymorphic DefDefs, create type skolems and assign them to the tparam trees.
1519 1621 val skolems = deriveFreshSkolems(tparams map (_.symbol))
1520 1622 map2(tparams, skolems)(_ setSymbol _)
1521 1623 }
@@ -1523,8 +1625,8 @@ trait Namers extends MethodSynthesis {
1523 1625 def completeImpl(sym: Symbol) = {
1524 1626 // @M an abstract type's type parameters are entered.
1525 1627 // TODO: change to isTypeMember ?
1526   - if (ownerSym.isAbstractType)
1527   - newNamerFor(ctx, owner) enterSyms tparams //@M
  1628 + if (defnSym.isAbstractType)
  1629 + newNamerFor(ctx, tree) enterSyms tparams //@M
1528 1630 restp complete sym
1529 1631 }
1530 1632 }
42 src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -453,12 +453,12 @@ trait Typers extends Modes with Adaptations with Tags {
453 453 def reenterValueParams(vparamss: List[List[ValDef]]) {
454 454 for (vparams <- vparamss)
455 455 for (vparam <- vparams)
456   - vparam.symbol = context.scope enter vparam.symbol
  456 + context.scope enter vparam.symbol
457 457 }
458 458
459 459 def reenterTypeParams(tparams: List[TypeDef]): List[Symbol] =
460 460 for (tparam <- tparams) yield {
461   - tparam.symbol = context.scope enter tparam.symbol
  461 + context.scope enter tparam.symbol
462 462 tparam.symbol.deSkolemize
463 463 }
464 464
@@ -2064,13 +2064,23 @@ trait Typers extends Modes with Adaptations with Tags {
2064 2064 * @return ...
2065 2065 */
2066 2066 def typedValDef(vdef: ValDef): ValDef = {
2067   -// attributes(vdef)
  2067 + val sym = vdef.symbol
  2068 + val valDefTyper = {
  2069 + val maybeConstrCtx =
  2070 + if (sym.isParameter && sym.owner.isConstructor) context.makeConstructorContext
  2071 + else context
  2072 + newTyper(maybeConstrCtx.makeNewScope(vdef, sym))
  2073 + }
  2074 + valDefTyper.typedValDefImpl(vdef)
  2075 + }
  2076 +
  2077 + // use typedValDef instead. this version is called after creating a new context for the ValDef
  2078 + private def typedValDefImpl(vdef: ValDef) = {
2068 2079 val sym = vdef.symbol.initialize
2069   - val typer1 = constrTyperIf(sym.isParameter && sym.owner.isConstructor)
2070 2080 val typedMods = typedModifiers(vdef.mods)
2071 2081
2072 2082 sym.annotations.map(_.completeInfo)
2073   - var tpt1 = checkNoEscaping.privates(sym, typer1.typedType(vdef.tpt))
  2083 + val tpt1 = checkNoEscaping.privates(sym, typedType(vdef.tpt))
2074 2084 checkNonCyclic(vdef, tpt1)
2075 2085
2076 2086 if (sym.hasAnnotation(definitions.VolatileAttr) && !sym.isMutable)
@@ -2098,7 +2108,7 @@ trait Typers extends Modes with Adaptations with Tags {
2098 2108 else subst(tpt1.tpe.typeArgs(0))
2099 2109 else subst(tpt1.tpe)
2100 2110 } else tpt1.tpe
2101   - newTyper(typer1.context.make(vdef, sym)).transformedOrTyped(vdef.rhs, EXPRmode | BYVALmode, tpt2)
  2111 + transformedOrTyped(vdef.rhs, EXPRmode | BYVALmode, tpt2)
2102 2112 }
2103 2113 treeCopy.ValDef(vdef, typedMods, vdef.name, tpt1, checkDead(rhs1)) setType NoType
2104 2114 }
@@ -2397,13 +2407,12 @@ trait Typers extends Modes with Adaptations with Tags {
2397 2407 }
2398 2408
2399 2409 def typedTypeDef(tdef: TypeDef): TypeDef =
2400   - typerWithCondLocalContext(context.makeNewScope(tdef, tdef.symbol))(tdef.tparams.nonEmpty){
2401   - _.typedTypeDef0(tdef)
  2410 + typerWithCondLocalContext(context.makeNewScope(tdef, tdef.symbol))(tdef.tparams.nonEmpty) {
  2411 + _.typedTypeDefImpl(tdef)
2402 2412 }
2403 2413
2404   - // call typedTypeDef instead
2405   - // a TypeDef with type parameters must always be type checked in a new scope
2406   - private def typedTypeDef0(tdef: TypeDef): TypeDef = {
  2414 + // use typedTypeDef instead. this version is called after creating a new context for the TypeDef
  2415 + private def typedTypeDefImpl(tdef: TypeDef): TypeDef = {
2407 2416 tdef.symbol.initialize
2408 2417 reenterTypeParams(tdef.tparams)
2409 2418 val tparams1 = tdef.tparams mapConserve typedTypeDef
@@ -5363,10 +5372,14 @@ trait Typers extends Modes with Adaptations with Tags {
5363 5372 typed(docdef.definition, mode, pt)
5364 5373 }
5365 5374
  5375 + /**
  5376 + * The typer with the correct context for a method definition. If the method is a default getter for
  5377 + * a constructor default, the resulting typer has a constructor context (fixes SI-5543).
  5378 + */
5366 5379 def defDefTyper(ddef: DefDef) = {
5367   - val flag = ddef.mods.hasDefaultFlag && sym.owner.isModuleClass &&
  5380 + val isConstrDefaultGetter = ddef.mods.hasDefaultFlag && sym.owner.isModuleClass &&
5368 5381 nme.defaultGetterToMethod(sym.name) == nme.CONSTRUCTOR
5369   - newTyper(context.makeNewScope(ddef, sym)).constrTyperIf(flag)
  5382 + newTyper(context.makeNewScope(ddef, sym)).constrTyperIf(isConstrDefaultGetter)
5370 5383 }
5371 5384
5372 5385 def typedAlternative(alt: Alternative) = {
@@ -5653,7 +5666,6 @@ trait Typers extends Modes with Adaptations with Tags {
5653 5666 lastTreeToTyper = tree
5654 5667 indentTyping()
5655 5668
5656   - var alreadyTyped = false
5657 5669 val startByType = if (Statistics.canEnable) Statistics.pushTimer(byTypeStack, byTypeNanos(tree.getClass)) else null
5658 5670 if (Statistics.canEnable) Statistics.incCounter(visitsByType, tree.getClass)
5659 5671 try {
@@ -5663,7 +5675,7 @@ trait Typers extends Modes with Adaptations with Tags {
5663 5675 if (tree.hasSymbol) tree.symbol = NoSymbol
5664 5676 }
5665 5677
5666   - alreadyTyped = tree.tpe ne null
  5678 + val alreadyTyped = tree.tpe ne null
5667 5679 var tree1: Tree = if (alreadyTyped) tree else {
5668 5680 printTyping(
5669 5681 ptLine("typing %s: pt = %s".format(ptTree(tree), pt),
15 src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
@@ -32,19 +32,4 @@ trait ExistentialsAndSkolems {
32 32 }
33 33 (new Deskolemizer).typeSkolems
34 34 }
35   -
36   - /** Convert to corresponding type parameters all skolems of method
37   - * parameters which appear in `tparams`.
38   - */
39   - def deskolemizeTypeParams(tparams: List[Symbol])(tp: Type): Type = {
40   - class DeSkolemizeMap extends TypeMap {
41   - def apply(tp: Type): Type = tp match {
42   - case TypeRef(pre, sym, args) if sym.isTypeSkolem && (tparams contains sym.deSkolemize) =>
43   - mapOver(typeRef(NoPrefix, sym.deSkolemize, args))
44   - case _ =>
45   - mapOver(tp)
46   - }
47   - }
48   - new DeSkolemizeMap mapOver tp
49   - }
50 35 }
4 src/reflect/scala/reflect/internal/Symbols.scala
@@ -1188,6 +1188,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
1188 1188 * to generate a type of kind *
1189 1189 * for a term symbol, its usual type.
1190 1190 * See the tpe/tpeHK overrides in TypeSymbol for more.
  1191 + *
  1192 + * For type symbols, `tpe` is different than `info`. `tpe` returns a typeRef
  1193 + * to the type symbol, `info` returns the type information of the type symbol,
  1194 + * e.g. a ClassInfoType for classes or a TypeBounds for abstract types.
1191 1195 */
1192 1196 def tpe: Type = info
1193 1197 def tpeHK: Type = tpe
10 test/files/neg/t5543.check
... ... @@ -0,0 +1,10 @@
  1 +t5543.scala:3: error: not found: type T
  2 + def this(x: T) { this() }
  3 + ^
  4 +t5543.scala:11: error: not found: value x
  5 + def this(a: Int, b: Int = x) {
  6 + ^
  7 +t5543.scala:18: error: not found: value x
  8 + def this(a: Int = x) { this() }
  9 + ^
  10 +three errors found
19 test/files/neg/t5543.scala
... ... @@ -0,0 +1,19 @@
  1 +class C1 {
  2 + type T
  3 + def this(x: T) { this() }
  4 +}
  5 +
  6 +class C1a[T] {
  7 + def this(x: T) { this() } // works, no error here
  8 +}
  9 +
  10 +class C2(x: Int) {
  11 + def this(a: Int, b: Int = x) {
  12 + this(b)
  13 + }
  14 +}
  15 +
  16 +class C3 {
  17 + val x = 0
  18 + def this(a: Int = x) { this() }
  19 +}
6 test/files/neg/t6829.check
... ... @@ -1,6 +1,6 @@
1 1 t6829.scala:35: error: type mismatch;
2 2 found : AgentSimulation.this.state.type (with underlying type G#State)
3   - required: _10.State
  3 + required: _9.State
4 4 lazy val actions: Map[G#Agent,G#Action] = agents.map(a => a -> a.chooseAction(state)).toMap
5 5 ^
6 6 t6829.scala:45: error: trait AgentSimulation takes type parameters
@@ -17,12 +17,12 @@ t6829.scala:49: error: not found: value nextState
17 17 ^
18 18 t6829.scala:50: error: type mismatch;
19 19 found : s.type (with underlying type Any)
20   - required: _54.State where val _54: G
  20 + required: _53.State where val _53: G
21 21 val r = rewards(agent).r(s,a,s2)
22 22 ^
23 23 t6829.scala:51: error: type mismatch;
24 24 found : s.type (with underlying type Any)
25   - required: _51.State
  25 + required: _50.State
26 26 agent.learn(s,a,s2,r): G#Agent
27 27 ^
28 28 t6829.scala:53: error: not found: value nextState
4 test/files/pos/t1014.scala
... ... @@ -1,6 +1,8 @@
1 1 import scala.xml.{NodeSeq, Elem}
2 2
3   -class EO extends App with Moo{
  3 +class EO extends App with Moo {
  4 + // return type is Flog, inherited from overridden method.
  5 + // implicit conversions are applied because expected type `pt` is `Flog` when `computeType(rhs, pt)`.
4 6 def cat = <cat>dog</cat>
5 7
6 8 implicit def nodeSeqToFlog(in: Elem): Flog = new Flog(in)
1  test/files/pos/t1803.flags
... ... @@ -0,0 +1 @@
  1 +-Yinfer-argument-types
2  test/files/pos/t1803.scala
... ... @@ -0,0 +1,2 @@
  1 +class A { def foo[A](a: A) = a }
  2 +class B extends A { override def foo[A](b) = b }
6 test/files/run/t5543.check
... ... @@ -1,3 +1,9 @@
1 1 Test, 7, 119
2 2 m, 3, 19
3 3 Test, 5, 85
  4 +T
  5 +C
  6 +T
  7 +T
  8 +D
  9 +T
19 test/files/run/t5543.scala
@@ -22,5 +22,24 @@ object Test extends Function0[Int] {
22 22 println(sut.toString)
23 23 println(sut.m())
24 24 println(A.init()())
  25 +
  26 + println((new T.C()).x)
  27 + println((new T.D(0,0)).x)
  28 + }
  29 +}
  30 +
  31 +object T {
  32 + override def toString = "T"
  33 +
  34 + // `this` refers to T
  35 + class C(val x: Any = {println(this); this}) { // prints T
  36 + println(this) // prints C
  37 + override def toString() = "C"
  38 + }
  39 +
  40 + class D(val x: Any) {
  41 + override def toString() = "D"
  42 + // `this` refers again to T
  43 + def this(a: Int, b: Int, c: Any = {println(this); this}) { this(c); println(this) } // prints T, then prints D
25 44 }
26 45 }

0 comments on commit b74c33e

Please sign in to comment.
Something went wrong with that request. Please try again.