Skip to content

Commit dcedba7

Browse files
committed
fix lazy vars
clean up lazy vars more docs
1 parent 2bd99ee commit dcedba7

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5261,7 +5261,7 @@ void DefaultArgumentInitializer::changeFunction(
52615261
}
52625262

52635263
auto param = paramList->get(getIndex());
5264-
if (param->isDefaultArgument())
5264+
if (param->getDefaultValue() || param->getStoredProperty())
52655265
param->setDefaultArgumentInitContext(this);
52665266
}
52675267

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3366,7 +3366,7 @@ void DelayedArgument::emitDefaultArgument(SILGenFunction &SGF,
33663366
SGFContext());
33673367
}
33683368
}
3369-
}
3369+
}
33703370

33713371
if (!isStoredPropertyDefaultArg) {
33723372
value = SGF.emitApplyOfDefaultArgGenerator(info.loc,

lib/Sema/CodeSynthesis.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,7 +1658,9 @@ static void maybeAddMemberwiseDefaultArg(ParamDecl *arg, VarDecl *var,
16581658
// If we don't have an expression initializer or silgen can't assign a default
16591659
// initializer, then we can't generate a default value. An example of where
16601660
// silgen can assign a default is var x: Int? where the default is nil.
1661-
if (!var->getParentPatternBinding()->isDefaultInitializable())
1661+
// If the variable is lazy, go ahead and give it a default value.
1662+
if (!var->getAttrs().hasAttribute<LazyAttr>() &&
1663+
!var->getParentPatternBinding()->isDefaultInitializable())
16621664
return;
16631665

16641666
// We can add a default value now.
@@ -1670,18 +1672,21 @@ static void maybeAddMemberwiseDefaultArg(ParamDecl *arg, VarDecl *var,
16701672

16711673
defaultInits.push_back(initDC);
16721674

1675+
// If the variable has a type T? and no initial value, return a nil literal
1676+
// default arg. All lazy variables return a nil literal as well. *Note* that
1677+
// the type will always be a sugared T? because we don't default init an
1678+
// explicit Optional<T>.
1679+
if ((isa<OptionalType>(var->getValueInterfaceType().getPointer()) &&
1680+
!var->getParentInitializer()) ||
1681+
var->getAttrs().hasAttribute<LazyAttr>()) {
1682+
arg->setDefaultArgumentKind(DefaultArgumentKind::NilLiteral);
1683+
return;
1684+
}
1685+
16731686
// Set the default value to the variable. When we emit this in silgen
16741687
// we're going to call the variable's initializer expression.
16751688
arg->setStoredProperty(var);
16761689
arg->setDefaultArgumentKind(DefaultArgumentKind::StoredProperty);
1677-
1678-
// If the type is T? and has no initial value, then set the default arg kind
1679-
// to nil literal. This is useful when we need to print the constructor.
1680-
// Note, this will always be the sugared T? because we don't default init an
1681-
// explicit Optional<T>.
1682-
if (isa<OptionalType>(var->getValueInterfaceType().getPointer()) &&
1683-
!var->getParentInitializer())
1684-
arg->setDefaultArgumentKind(DefaultArgumentKind::NilLiteral);
16851690
}
16861691

16871692
/// Create an implicit struct or class constructor.

test/SILGen/stored_property_default_arg.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,24 @@ struct F<T> {
3838
// CHECK-NEXT: {{.*}} = apply [[F1_REF]]<Int>({{.*}}, {{.*}}, [[H1]], {{.*}}) : $@convention(method) <τ_0_0> (@in τ_0_0, Int, @thin F<τ_0_0>.Type) -> @out F<τ_0_0>
3939

4040
let i = F(g: 128)
41+
42+
struct J {
43+
lazy var k: Bool = false
44+
lazy var l: Int = 0
45+
}
46+
47+
// CHECK: {{.*}} = metatype $@thin Optional<Int>.Type
48+
// CHECK-NEXT: [[L1_REF:%.*]] = enum $Optional<Int>, #Optional.none!enumelt
49+
// CHECK-NEXT: function_ref J.init(k:l:)
50+
// CHECK-NEXT: [[J1_REF:%.*]] = function_ref @$s27stored_property_default_arg1JV1k1lACSbSg_SiSgtcfC : $@convention(method) (Optional<Bool>, Optional<Int>, @thin J.Type) -> J
51+
// CHECK-NEXT: {{.*}} = apply [[J1_REF]]({{.*}}, [[L1_REF]], {{.*}}) : $@convention(method) (Optional<Bool>, Optional<Int>, @thin J.Type) -> J
52+
53+
let m = J(k: true)
54+
55+
// CHECK: {{.*}} = metatype $@thin Optional<Bool>.Type
56+
// CHECK-NEXT: [[K1_REF:%.*]] = enum $Optional<Bool>, #Optional.none!enumelt
57+
// CHECK-NEXT: function_ref J.init(k:l:)
58+
// CHECK-NEXT: [[J2_REF:%.*]] = function_ref @$s27stored_property_default_arg1JV1k1lACSbSg_SiSgtcfC : $@convention(method) (Optional<Bool>, Optional<Int>, @thin J.Type) -> J
59+
// CHECK-NEXT: {{.*}} = apply [[J2_REF]]([[K1_REF]], {{.*}}, {{.*}}) : $@convention(method) (Optional<Bool>, Optional<Int>, @thin J.Type) -> J
60+
61+
let n = J(l: 316)

0 commit comments

Comments
 (0)