@@ -348,6 +348,16 @@ class Typer extends Namer
348
348
findRefRecur(NoType , BindingPrec .NothingBound , NoContext )
349
349
}
350
350
351
+ def toNotNullTermRef (tree : Tree , pt : Type )(implicit ctx : Context ): Tree = tree.tpe match
352
+ case tp @ OrNull (tpnn) : TermRef
353
+ if pt != AssignProto && // Ensure it is not the lhs of Assign
354
+ ctx.notNullInfos.impliesNotNull(tp) =>
355
+ Apply (
356
+ TypeApply (Ident (defn.Compiletime_notNull .namedType), TypeTree (tpnn) :: Nil ),
357
+ tree :: Nil )
358
+ case _ =>
359
+ tree
360
+
351
361
/** Attribute an identifier consisting of a simple name or wildcard
352
362
*
353
363
* @param tree The tree representing the identifier.
@@ -418,18 +428,7 @@ class Typer extends Namer
418
428
tree.withType(ownType)
419
429
}
420
430
421
- val tree2 = ownType match {
422
- case ot : TermRef
423
- if ctx.explicitNulls &&
424
- pt != AssignProto && // Ensure it is not the lhs of Assign
425
- ctx.notNullInfos.impliesNotNull(ot) =>
426
- Apply (
427
- TypeApply (Ident (defn.Compiletime_notNull .namedType), TypeTree (ownType.stripNull) :: Nil ),
428
- tree1 :: Nil )
429
- case _ =>
430
- tree1
431
- }
432
-
431
+ val tree2 = toNotNullTermRef(tree1, pt)
433
432
434
433
checkStableIdentPattern(tree2, pt)
435
434
}
@@ -456,8 +455,11 @@ class Typer extends Namer
456
455
case qual =>
457
456
if (tree.name.isTypeName) checkStable(qual.tpe, qual.sourcePos)
458
457
val select = assignType(cpy.Select (tree)(qual, tree.name), qual)
459
- if (select.tpe ne TryDynamicCallType ) ConstFold (checkStableIdentPattern(select, pt))
460
- else if (pt.isInstanceOf [FunOrPolyProto ] || pt == AssignProto ) select
458
+
459
+ val select1 = toNotNullTermRef(select, pt)
460
+
461
+ if (select1.tpe ne TryDynamicCallType ) ConstFold (checkStableIdentPattern(select1, pt))
462
+ else if (pt.isInstanceOf [FunOrPolyProto ] || pt == AssignProto ) select1
461
463
else typedDynamicSelect(tree, Nil , pt)
462
464
}
463
465
@@ -2220,27 +2222,31 @@ class Typer extends Namer
2220
2222
case Some (xtree) =>
2221
2223
traverse(xtree :: rest)
2222
2224
case none =>
2223
- val defCtx = mdef match
2225
+ def defCtx = ctx.withNotNullInfos(initialNotNullInfos)
2226
+ val newCtx = if (ctx.owner.isTerm) {
2224
2227
// Keep preceding not null facts in the current context only if `mdef`
2225
2228
// cannot be executed out-of-sequence.
2226
- case _ : ValDef if ! mdef.mods.is(Lazy ) && ctx.owner.isTerm =>
2227
- ctx // all preceding statements will have been executed in this case
2228
- case _ =>
2229
- ctx.withNotNullInfos(initialNotNullInfos)
2230
- // We have to check the Completer of symbol befor typedValDef,
2231
- // otherwise the symbol is already completed using creation context.
2232
- mdef.getAttachment(SymOfTree ).map(s => (s, s.infoOrCompleter)) match {
2233
- case Some ((sym, completer : Namer # Completer ))
2234
- if completer.creationContext.notNullInfos ne defCtx.notNullInfos =>
2235
- // The RHS of a val def should know about not null facts established
2236
- // in preceding statements (unless the ValDef is completed ahead of time,
2237
- // then it is impossible).
2238
- sym.info = Completer (completer.original)(
2239
- given completer .creationContext.withNotNullInfos(defCtx.notNullInfos))
2240
- case _ =>
2229
+ // We have to check the Completer of symbol befor typedValDef,
2230
+ // otherwise the symbol is already completed using creation context.
2231
+ mdef.getAttachment(SymOfTree ).map(s => (s, s.infoOrCompleter)) match {
2232
+ case Some ((sym, completer : Namer # Completer )) =>
2233
+ if (completer.creationContext.notNullInfos ne ctx.notNullInfos)
2234
+ // The RHS of a val def should know about not null facts established
2235
+ // in preceding statements (unless the DefTree is completed ahead of time,
2236
+ // then it is impossible).
2237
+ sym.info = Completer (completer.original)(
2238
+ given completer .creationContext.withNotNullInfos(ctx.notNullInfos))
2239
+ ctx // all preceding statements will have been executed in this case
2240
+ case _ =>
2241
+ // If it has been completed, then it must be because there is a forward reference
2242
+ // to the definition in the program. Hence, we don't Keep preceding not null facts
2243
+ // in the current context.
2244
+ defCtx
2245
+ }
2241
2246
}
2247
+ else defCtx
2242
2248
2243
- typed(mdef)(given defCtx ) match {
2249
+ typed(mdef)(given newCtx ) match {
2244
2250
case mdef1 : DefDef if ! Inliner .bodyToInline(mdef1.symbol).isEmpty =>
2245
2251
buf += inlineExpansion(mdef1)
2246
2252
// replace body with expansion, because it will be used as inlined body
0 commit comments