git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@16540 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
c6f5bc3c56
commit
baba226b01
|
@ -1903,6 +1903,15 @@ A type's typeSymbol should never be inspected directly.
|
|||
}
|
||||
}
|
||||
|
||||
// ** Replace formal type parameter symbols with actual type arguments. * /
|
||||
override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]) = {
|
||||
val attributes1 = attributes.map(info => AnnotationInfo(info.atp.instantiateTypeParams(
|
||||
formals, actuals), info.args, info.assocs))
|
||||
val underlying1 = underlying.instantiateTypeParams(formals, actuals)
|
||||
if ((attributes1 eq attributes) && (underlying1 eq underlying)) this
|
||||
else AnnotatedType(attributes1, underlying1, selfsym)
|
||||
}
|
||||
|
||||
/** Return the base type sequence of tp, dropping the annotations, unless the base type sequence of tp
|
||||
* is precisely tp itself. */
|
||||
override def baseTypeSeq: BaseTypeSeq = {
|
||||
|
|
|
@ -64,6 +64,18 @@ trait Variances {
|
|||
v
|
||||
}
|
||||
|
||||
/** Compute variance of type parameter `tparam' in all type annotations `attribs'. */
|
||||
def varianceInAttribs(attribs: List[AnnotationInfo])(tparam: Symbol): Int = {
|
||||
(VARIANCES /: attribs) ((v, attrib) => v & varianceInAttrib(attrib)(tparam))
|
||||
}
|
||||
|
||||
/** Compute variance of type parameter `tparam' in type annotation `attrib'. */
|
||||
def varianceInAttrib(attrib: AnnotationInfo)(tparam: Symbol): Int = {
|
||||
varianceInType(attrib.atp)(tparam)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Compute variance of type parameter <code>tparam</code> in type <code>tp</code>. */
|
||||
def varianceInType(tp: Type)(tparam: Symbol): Int = tp match {
|
||||
case ErrorType | WildcardType | NoType | NoPrefix | ThisType(_) | ConstantType(_) =>
|
||||
|
@ -84,6 +96,6 @@ trait Variances {
|
|||
case ExistentialType(tparams, restpe) =>
|
||||
varianceInSyms(tparams)(tparam) & varianceInType(restpe)(tparam)
|
||||
case AnnotatedType(attribs, tp, _) =>
|
||||
varianceInType(tp)(tparam)
|
||||
varianceInAttribs(attribs)(tparam) & varianceInType(tp)(tparam)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
defined class posingAs
|
||||
resolve: [A,B](A @posingAs[B])B
|
||||
x: Any = 7
|
|
@ -0,0 +1,44 @@
|
|||
import scala.tools.nsc._
|
||||
|
||||
object Test {
|
||||
|
||||
/**
|
||||
* Type inference overlooks constraints posed by type parameters in annotations on types.
|
||||
*/
|
||||
|
||||
val testCode = <code>
|
||||
|
||||
class posingAs[A] extends TypeConstraint
|
||||
|
||||
def resolve[A,B](x: A @posingAs[B]): B = x.asInstanceOf[B]
|
||||
|
||||
val x = resolve(7: @posingAs[Any])
|
||||
|
||||
</code>.text
|
||||
|
||||
def main(args: Array[String]) = {
|
||||
|
||||
val tool = new Interpreter(new Settings())
|
||||
val global = tool.compiler
|
||||
|
||||
import global._
|
||||
import definitions._
|
||||
|
||||
object checker extends AnnotationChecker {
|
||||
|
||||
/** Check annotations to decide whether tpe1 <:< tpe2 */
|
||||
def annotationsConform(tpe1: Type, tpe2: Type): Boolean = {
|
||||
|
||||
tpe1.attributes.forall(a1 => tpe2.attributes.forall(a2 => a1.atp <:< a2.atp))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
global.addAnnotationChecker(checker)
|
||||
|
||||
tool.interpret(testCode)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
defined class xyz
|
||||
loopWhile: [T](=> Boolean)(=> Unit @xyz[T])Unit @xyz[T]
|
||||
test: ()Unit @xyz[Int]
|
|
@ -0,0 +1,55 @@
|
|||
import scala.tools.nsc._
|
||||
|
||||
object Test {
|
||||
|
||||
/**
|
||||
* ...
|
||||
*/
|
||||
|
||||
val testCode = <code>
|
||||
|
||||
class xyz[A] extends TypeConstraint
|
||||
|
||||
def loopWhile[T](cond: =>Boolean)(body: =>(Unit @xyz[T])): Unit @ xyz[T] = {{
|
||||
if (cond) {{
|
||||
body
|
||||
loopWhile[T](cond)(body)
|
||||
}}
|
||||
}}
|
||||
|
||||
def test() = {{
|
||||
var x = 7
|
||||
loopWhile(x != 0) {{
|
||||
x = x - 1
|
||||
(): @xyz[Int]
|
||||
}}
|
||||
}}
|
||||
|
||||
</code>.text
|
||||
|
||||
def main(args: Array[String]) = {
|
||||
|
||||
val tool = new Interpreter(new Settings())
|
||||
val global = tool.compiler
|
||||
|
||||
import global._
|
||||
import definitions._
|
||||
|
||||
object checker extends AnnotationChecker {
|
||||
|
||||
/** Check annotations to decide whether tpe1 <:< tpe2 */
|
||||
def annotationsConform(tpe1: Type, tpe2: Type): Boolean = {
|
||||
|
||||
tpe1.attributes.forall(a1 => tpe2.attributes.forall(a2 => a1.atp <:< a2.atp))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
global.addAnnotationChecker(checker)
|
||||
|
||||
tool.interpret(testCode)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue