@@ -15,7 +15,7 @@ import util.NoSourcePosition
1515import reporting .trace
1616import config .Printers .init
1717
18- import Effects ._ , Potentials ._ , Summary ._ , Util ._
18+ import Effects ._ , Potentials ._ , Summary ._ , Util ._ , Errors . _
1919
2020object Checking {
2121 /** The checking state
@@ -41,26 +41,6 @@ object Checking {
4141 visited += eff
4242 copy(path = this .path :+ eff.source)
4343 }
44-
45- def trace (implicit state : State ): String = {
46- var indentCount = 0
47- var last = " "
48- val sb = new StringBuilder
49- this .path.foreach { tree =>
50- indentCount += 1
51- val pos = tree.sourcePos
52- val line = " [ " + pos.source.file.name + " :" + (pos.line + 1 ) + " ]"
53- if (last != line)
54- sb.append(
55- if (pos.source.exists)
56- i " ${ " " * indentCount }-> ${pos.lineContent.trim}\t $line\n "
57- else
58- i " ${tree.show}\n "
59- )
60- last = line
61- }
62- sb.toString
63- }
6444 }
6545
6646 private implicit def theEnv (implicit state : State ): Env = state.env
@@ -158,66 +138,36 @@ object Checking {
158138 }
159139 }
160140
161- private def nonInitError (field : Symbol )(implicit state : State ) = {
162- traceIndented(" initialized: " + state.fieldsInited, init)
163-
164- // should issue error, use warning so that it will continue compile subprojects
165- theCtx.warning(
166- " Access non-initialized field " + field.show +
167- " . Calling trace:\n " + state.trace,
168- field.sourcePos
169- )
170- }
171-
172- private def externalCallError (sym : Symbol , source : Tree )(implicit state : State ) =
173- theCtx.warning(
174- " Calling the external method " + sym.show +
175- " may cause initialization errors" +
176- " . Calling trace:\n " + state.trace,
177- source.sourcePos
178- )
179-
180141 private def checkEffectsIn (effs : Effects , cls : ClassSymbol )(implicit state : State ): Unit = {
181142 val rebased = Effects .asSeenFrom(effs, ThisRef (state.thisClass)(null ), cls, Potentials .empty)
182143 rebased.foreach { check(_) }
183144 }
184145
185- private def check (eff : Effect )(implicit state : State ): Unit =
186- if (! state.visited.contains(eff)) traceOp (" checking effect " + eff.show, init) {
146+ private def check (eff : Effect )(implicit state : State ): Errors =
147+ if (state.visited.contains(eff)) Errors .empty else trace (" checking effect " + eff.show, init, errs => Errors .show(errs. asInstanceOf [ Errors ]) ) {
187148 implicit val state2 : State = state.withVisited(eff)
188149
189150 eff match {
190151 case Promote (pot) =>
191152 pot match {
192- case ThisRef (cls) =>
153+ case pot @ ThisRef (cls) =>
193154 assert(cls == state.thisClass, " unexpected potential " + pot.show)
194-
195- theCtx.warning(
196- " Promote `this` to be initialized while it is not. Calling trace:\n " + state.trace,
197- eff.source.sourcePos
198- )
155+ PromoteThis (pot, eff.source, state.path).toErrors
199156
200157 case _ : Cold =>
201- theCtx.warning(
202- " Promoting the value " + eff.source.show + " to be initialized while it is under initialization" +
203- " . Calling trace:\n " + state.trace,
204- eff.source.sourcePos
205- )
158+ PromoteCold (eff.source, state.path).toErrors
206159
207- case Warm (cls, outer) =>
208- theCtx.warning(
209- " Promoting the value under initialization to be initialized: " + pot.source.show +
210- " . Calling trace:\n " + state.trace,
211- eff.source.sourcePos
212- )
160+ case pot @ Warm (cls, outer) =>
161+ PromoteWarm (pot, eff.source, state.path).toErrors
213162
214163 case Fun (pots, effs) =>
215- effs.foreach { check(_) }
216- pots.foreach { pot => check(Promote (pot)(eff.source)) }
164+ val errs1 = effs.flatMap { check(_) }
165+ val errs2 = pots.flatMap { pot => check(Promote (pot)(eff.source)) }
166+ UnsafePromotion (pot, eff.source, state.path, errs1 ++ errs2).toErrors
217167
218168 case pot =>
219169 val pots = expand(pot)
220- pots.foreach { pot => check(Promote (pot)(eff.source)) }
170+ pots.flatMap { pot => check(Promote (pot)(eff.source)) }
221171 }
222172
223173 case FieldAccess (pot, field) =>
@@ -228,33 +178,32 @@ object Checking {
228178
229179 val target = resolve(cls, field)
230180 if (target.is(Flags .Lazy )) check(MethodCall (pot, target)(eff.source))
231- else if (! state.fieldsInited.contains(target)) nonInitError(target)
181+ else if (! state.fieldsInited.contains(target)) AccessNonInit (target, state.path).toErrors
182+ else Errors .empty
232183
233184 case SuperRef (ThisRef (cls), supercls) =>
234185 assert(cls == state.thisClass, " unexpected potential " + pot.show)
235186
236187 val target = resolveSuper(cls, supercls, field)
237188 if (target.is(Flags .Lazy )) check(MethodCall (pot, target)(eff.source))
238- else if (! state.fieldsInited.contains(target)) nonInitError(target)
189+ else if (! state.fieldsInited.contains(target)) AccessNonInit (target, state.path).toErrors
190+ else Errors .empty
239191
240192 case Warm (cls, outer) =>
241193 // all fields of warm values are initialized
242194 val target = resolve(cls, field)
243195 if (target.is(Flags .Lazy )) check(MethodCall (pot, target)(eff.source))
196+ else Errors .empty
244197
245198 case _ : Cold =>
246- theCtx.warning(
247- " Access field " + eff.source.show + " on a known value under initialization" +
248- " . Calling trace:\n " + state.trace,
249- eff.source.sourcePos
250- )
199+ AccessCold (field, eff.source, state.path).toErrors
251200
252201 case Fun (pots, effs) =>
253202 throw new Exception (" Unexpected effect " + eff.show)
254203
255204 case pot =>
256205 val pots = expand(pot)
257- pots.foreach { pot => check(FieldAccess (pot, field)(eff.source)) }
206+ pots.flatMap { pot => check(FieldAccess (pot, field)(eff.source)) }
258207 }
259208
260209 case MethodCall (pot, sym) =>
@@ -267,9 +216,9 @@ object Checking {
267216 check(FieldAccess (pot, target)(eff.source))
268217 else if (target.isInternal) {
269218 val effs = thisRef.effectsOf(target)
270- effs.foreach { check(_) }
219+ effs.flatMap { check(_) }
271220 }
272- else externalCallError (target, eff.source)
221+ else CallUnknown (target, eff.source, state.path).toErrors
273222
274223 case SuperRef (thisRef @ ThisRef (cls), supercls) =>
275224 assert(cls == state.thisClass, " unexpected potential " + pot.show)
@@ -279,37 +228,32 @@ object Checking {
279228 check(FieldAccess (pot, target)(eff.source))
280229 else if (target.isInternal) {
281230 val effs = thisRef.effectsOf(target)
282- effs.foreach { check(_) }
231+ effs.flatMap { check(_) }
283232 }
284- else externalCallError (target, eff.source)
233+ else CallUnknown (target, eff.source, state.path).toErrors
285234
286235 case warm @ Warm (cls, outer) =>
287236 val target = resolve(cls, sym)
288237
289238 if (target.isInternal) {
290239 val effs = warm.effectsOf(target)
291- effs.foreach { check(_) }
240+ effs.flatMap { check(_) }
292241 }
293- else if (! sym.isConstructor) externalCallError(target, eff.source)
242+ else if (! sym.isConstructor) CallUnknown (target, eff.source, state.path).toErrors
243+ else Errors .empty
294244
295245 case _ : Cold =>
296- theCtx.warning(
297- " Call method " + eff.source.show + " on a cold value" +
298- " . Calling trace:\n " + state.trace,
299- eff.source.sourcePos
300- )
246+ CallCold (sym, eff.source, state.path).toErrors
301247
302248 case Fun (pots, effs) =>
303249 // TODO: assertion might be false, due to SAM
304- if (sym.name.toString == " apply" ) {
305- effs.foreach { check(_) }
306- pots.foreach { pot => check(Promote (pot)(eff.source)) }
307- }
250+ if (sym.name.toString == " apply" ) effs.flatMap { check(_) }
251+ else Errors .empty
308252 // curried, tupled, toString are harmless
309253
310254 case pot =>
311255 val pots = expand(pot)
312- pots.foreach { pot =>
256+ pots.flatMap { pot =>
313257 check(MethodCall (pot, sym)(eff.source))
314258 }
315259 }
0 commit comments