Skip to content

Commit

Permalink
SI-6829, SI-6788, NPEs during erroneous compilation.
Browse files Browse the repository at this point in the history
Have to intercept trees which have a null type due to errors
before they leave the warm confines of 'def typed' because from
that point everything assumes tree.tpe != null.
  • Loading branch information
paulp committed Dec 24, 2012
1 parent 5666468 commit 231d59d
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5264,7 +5264,7 @@ trait Typers extends Modes with Adaptations with Tags {

def typedDocDef(docdef: DocDef) = {
if (forScaladoc && (sym ne null) && (sym ne NoSymbol)) {
val comment = docdef.comment
val comment = docdef.comment
docComments(sym) = comment
comment.defineVariables(sym)
val typer1 = newTyper(context.makeNewScope(tree, context.owner))
Expand Down Expand Up @@ -5595,12 +5595,18 @@ trait Typers extends Modes with Adaptations with Tags {
"context.owner" -> context.owner
)
)
val tree1 = typed1(tree, mode, dropExistential(pt))
typed1(tree, mode, dropExistential(pt))
}
// Can happen during erroneous compilation - error(s) have been
// reported, but we need to avoid causing an NPE with this tree
if (tree1.tpe eq null)
return setError(tree)

if (!alreadyTyped) {
printTyping("typed %s: %s%s".format(
ptTree(tree1), tree1.tpe,
if (isSingleType(tree1.tpe)) " with underlying "+tree1.tpe.widen else "")
)
tree1
}

tree1.tpe = addAnnotations(tree1, tree1.tpe)
Expand Down
5 changes: 5 additions & 0 deletions test/files/neg/t6788.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
t6788.scala:6: error: not found: value foo
Error occurred in an application involving default arguments.
s.copy(b = foo)
^
one error found
7 changes: 7 additions & 0 deletions test/files/neg/t6788.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
case class B[T](b: T, a: List[Int]) // need two args, B must be polymorphic

class A {
var s: B[Int] = _ // has to be a var

s.copy(b = foo)
}
36 changes: 36 additions & 0 deletions test/files/neg/t6829.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
t6829.scala:35: error: type mismatch;
found : AgentSimulation.this.state.type (with underlying type G#State)
required: _10.State
lazy val actions: Map[G#Agent,G#Action] = agents.map(a => a -> a.chooseAction(state)).toMap
^
t6829.scala:45: error: trait AgentSimulation takes type parameters
pastHistory: List[G#State] = Nil) extends AgentSimulation
^
t6829.scala:47: error: class LearningSimulation takes type parameters
lazy val step: LearningSimulation = {
^
t6829.scala:49: error: not found: value actions
val (s,a,s2) = (state,actions(agent),nextState)
^
t6829.scala:49: error: not found: value nextState
val (s,a,s2) = (state,actions(agent),nextState)
^
t6829.scala:50: error: type mismatch;
found : s.type (with underlying type Any)
required: _54.State where val _54: G
val r = rewards(agent).r(s,a,s2)
^
t6829.scala:51: error: type mismatch;
found : s.type (with underlying type Any)
required: _51.State
agent.learn(s,a,s2,r): G#Agent
^
t6829.scala:53: error: not found: value nextState
Error occurred in an application involving default arguments.
copy(agents = updatedAgents, state = nextState, pastHistory = currentHistory)
^
t6829.scala:53: error: not found: value currentHistory
Error occurred in an application involving default arguments.
copy(agents = updatedAgents, state = nextState, pastHistory = currentHistory)
^
9 errors found
64 changes: 64 additions & 0 deletions test/files/neg/t6829.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package bugs

/**
* Created with IntelliJ IDEA.
* User: arya
* Date: 12/18/12
* Time: 4:17 PM
* To change this template use File | Settings | File Templates.
*/
object currenttype2 {

type Reward = Double

trait AbstractAgent[State,Action] {
type A = AbstractAgent[State,Action]
def chooseAction(s: State): Action
def startEpisode: A = this
def learn(s1: State, a: Action, s2: State, r: Reward): A
}

case class RewardFunction[State,Action](r: (State,Action,State) => Reward)

trait Rules[G<:GameDomain] {
def simulate(state: G#State, agentActions: List[(G#Agent,G#Action)]): G#State
}

trait AgentSimulation[G<:GameDomain] {
val agents: List[G#Agent]
val state: G#State
val rewards: Map[G#Agent,G#Rewards]
val rules: Rules[G]
val pastHistory: List[G#State]
lazy val currentHistory = state :: pastHistory

lazy val actions: Map[G#Agent,G#Action] = agents.map(a => a -> a.chooseAction(state)).toMap
lazy val nextState: G#State = rules.simulate(state, actions.toList)

def step: AgentSimulation[G]
}

case class LearningSimulation[G<:GameDomain](agents: List[G#Agent],
state: G#State,
rewards: Map[G#Agent,G#Rewards],
rules: Rules[G],
pastHistory: List[G#State] = Nil) extends AgentSimulation
{
lazy val step: LearningSimulation = {
val updatedAgents: List[G#Agent] = agents map { agent =>
val (s,a,s2) = (state,actions(agent),nextState)
val r = rewards(agent).r(s,a,s2)
agent.learn(s,a,s2,r): G#Agent
}
copy(agents = updatedAgents, state = nextState, pastHistory = currentHistory)
}
}

trait GameDomain {
domain =>
type State
type Action
type Agent = AbstractAgent[State, Action] // agent supertype
type Rewards = RewardFunction[State,Action]
}
}

0 comments on commit 231d59d

Please sign in to comment.