@@ -2713,117 +2713,139 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
2713
2713
Identifier name = ctx.getIdentifier (nameBuf);
2714
2714
2715
2715
auto dc = var->getDeclContext ();
2716
+ VarDecl *backingVar = nullptr ;
2717
+ VarDecl *projectionVar = nullptr ;
2718
+
2716
2719
if (auto *param = dyn_cast<ParamDecl>(var)) {
2717
- auto * backingVar = ParamDecl::cloneWithoutType (ctx, param);
2720
+ backingVar = ParamDecl::cloneWithoutType (ctx, param);
2718
2721
backingVar->setName (name);
2719
2722
Type wrapperType;
2720
2723
2721
2724
// If this is a function parameter, compute the backing
2722
2725
// type now. For closure parameters, let the constraint
2723
2726
// system infer the backing type.
2724
- if (dc-> getAsDecl ()) {
2727
+ if (!var-> getInterfaceType ()-> hasError ()) {
2725
2728
wrapperType = var->getPropertyWrapperBackingPropertyType ();
2726
2729
if (!wrapperType || wrapperType->hasError ())
2727
2730
return PropertyWrapperBackingPropertyInfo ();
2728
2731
2729
2732
backingVar->setInterfaceType (wrapperType);
2730
2733
}
2731
2734
2732
- VarDecl *projectionVar = nullptr ;
2733
2735
if (wrapperInfo.projectedValueVar || var->getName ().hasDollarPrefix ()) {
2734
2736
projectionVar =
2735
2737
synthesizePropertyWrapperProjectionVar (ctx, var, wrapperType,
2736
2738
wrapperInfo.projectedValueVar );
2737
2739
}
2738
-
2739
- return PropertyWrapperBackingPropertyInfo (backingVar, projectionVar);
2740
2740
}
2741
2741
2742
2742
if (!wrapperInfo)
2743
- return PropertyWrapperBackingPropertyInfo ();
2743
+ return PropertyWrapperBackingPropertyInfo (backingVar, projectionVar );
2744
2744
2745
2745
// Determine the type of the storage.
2746
2746
auto wrapperType = var->getPropertyWrapperBackingPropertyType ();
2747
2747
if (!wrapperType || wrapperType->hasError ())
2748
- return PropertyWrapperBackingPropertyInfo ();
2748
+ return PropertyWrapperBackingPropertyInfo (backingVar, projectionVar);
2749
+
2749
2750
Type storageInterfaceType = wrapperType;
2750
2751
Type storageType = dc->mapTypeIntoContext (storageInterfaceType);
2751
2752
2752
2753
// Create the backing storage property and note it in the cache.
2753
- VarDecl *backingVar = new (ctx) VarDecl (/* IsStatic=*/ var->isStatic (),
2754
- VarDecl::Introducer::Var,
2755
- var->getLoc (),
2756
- name, dc);
2757
- backingVar->setInterfaceType (storageInterfaceType);
2758
- backingVar->setImplicit ();
2759
- backingVar->setOriginalWrappedProperty (var);
2760
-
2761
- // The backing storage is 'private'.
2762
- backingVar->overwriteAccess (AccessLevel::Private);
2763
- backingVar->overwriteSetterAccess (AccessLevel::Private);
2764
-
2765
- addMemberToContextIfNeeded (backingVar, dc, var);
2766
-
2767
- // Create the pattern binding declaration for the backing property.
2768
- Pattern *pbdPattern = NamedPattern::createImplicit (ctx, backingVar);
2769
- pbdPattern->setType (storageType);
2770
- pbdPattern = TypedPattern::createImplicit (ctx, pbdPattern, storageType);
2771
- auto pbd = PatternBindingDecl::createImplicit (
2772
- ctx, var->getCorrectStaticSpelling (), pbdPattern,
2773
- /* init*/ nullptr , dc, SourceLoc ());
2774
- addMemberToContextIfNeeded (pbd, dc, var);
2775
- pbd->setStatic (var->isStatic ());
2776
-
2777
- // Take the initializer from the original property.
2778
- auto parentPBD = var->getParentPatternBinding ();
2779
- unsigned patternNumber = parentPBD->getPatternEntryIndexForVarDecl (var);
2780
-
2781
- // Force the default initializer to come into existence, if there is one,
2782
- // and the wrapper doesn't provide its own.
2783
- if (!parentPBD->isInitialized (patternNumber)
2784
- && parentPBD->isDefaultInitializable (patternNumber)
2785
- && !wrapperInfo.defaultInit ) {
2786
- auto ty = parentPBD->getPattern (patternNumber)->getType ();
2787
- if (auto defaultInit = TypeChecker::buildDefaultInitializer (ty))
2788
- parentPBD->setInit (patternNumber, defaultInit);
2789
- }
2790
-
2791
- if (parentPBD->isInitialized (patternNumber) &&
2792
- !parentPBD->isInitializerChecked (patternNumber)) {
2793
- TypeChecker::typeCheckPatternBinding (parentPBD, patternNumber);
2754
+ PatternBindingDecl *pbd = nullptr ;
2755
+ if (!backingVar) {
2756
+ backingVar = new (ctx) VarDecl (/* IsStatic=*/ var->isStatic (),
2757
+ VarDecl::Introducer::Var,
2758
+ var->getLoc (),
2759
+ name, dc);
2760
+ backingVar->setInterfaceType (storageInterfaceType);
2761
+ backingVar->setImplicit ();
2762
+ backingVar->setOriginalWrappedProperty (var);
2763
+
2764
+ // The backing storage is 'private'.
2765
+ backingVar->overwriteAccess (AccessLevel::Private);
2766
+ backingVar->overwriteSetterAccess (AccessLevel::Private);
2767
+
2768
+ addMemberToContextIfNeeded (backingVar, dc, var);
2769
+
2770
+ // Create the pattern binding declaration for the backing property.
2771
+ Pattern *pbdPattern = NamedPattern::createImplicit (ctx, backingVar);
2772
+ pbdPattern->setType (storageType);
2773
+ pbdPattern = TypedPattern::createImplicit (ctx, pbdPattern, storageType);
2774
+ pbd = PatternBindingDecl::createImplicit (ctx, var->getCorrectStaticSpelling (), pbdPattern,
2775
+ /* init*/ nullptr , dc, SourceLoc ());
2776
+ addMemberToContextIfNeeded (pbd, dc, var);
2777
+ pbd->setStatic (var->isStatic ());
2794
2778
}
2795
2779
2796
2780
Expr *initializer = nullptr ;
2797
2781
PropertyWrapperValuePlaceholderExpr *wrappedValue = nullptr ;
2798
2782
2799
- if ((initializer = parentPBD->getInit (patternNumber))) {
2800
- pbd->setInit (0 , initializer);
2801
- pbd->setInitializerChecked (0 );
2802
- wrappedValue = findWrappedValuePlaceholder (initializer);
2803
- } else {
2804
- if (!parentPBD->isInitialized (patternNumber) && wrapperInfo.defaultInit ) {
2805
- // FIXME: Record this expression somewhere so that DI can perform the
2806
- // initialization itself.
2807
- Expr *initializer = nullptr ;
2808
- typeCheckSynthesizedWrapperInitializer (pbd, backingVar, parentPBD,
2809
- initializer);
2783
+ // Take the initializer from the original property.
2784
+ if (!isa<ParamDecl>(var)) {
2785
+ auto parentPBD = var->getParentPatternBinding ();
2786
+ unsigned patternNumber = parentPBD->getPatternEntryIndexForVarDecl (var);
2787
+
2788
+ // Force the default initializer to come into existence, if there is one,
2789
+ // and the wrapper doesn't provide its own.
2790
+ if (!parentPBD->isInitialized (patternNumber)
2791
+ && parentPBD->isDefaultInitializable (patternNumber)
2792
+ && !wrapperInfo.defaultInit ) {
2793
+ auto ty = parentPBD->getPattern (patternNumber)->getType ();
2794
+ if (auto defaultInit = TypeChecker::buildDefaultInitializer (ty))
2795
+ parentPBD->setInit (patternNumber, defaultInit);
2796
+ }
2797
+
2798
+ if (parentPBD->isInitialized (patternNumber) &&
2799
+ !parentPBD->isInitializerChecked (patternNumber)) {
2800
+ TypeChecker::typeCheckPatternBinding (parentPBD, patternNumber);
2801
+ }
2802
+
2803
+ if ((initializer = parentPBD->getInit (patternNumber))) {
2810
2804
pbd->setInit (0 , initializer);
2811
2805
pbd->setInitializerChecked (0 );
2812
- } else if (var->hasObservers () && !dc->isTypeContext ()) {
2813
- var->diagnose (diag::observingprop_requires_initializer);
2814
- }
2806
+ wrappedValue = findWrappedValuePlaceholder (initializer);
2807
+ } else {
2808
+ if (!parentPBD->isInitialized (patternNumber) && wrapperInfo.defaultInit ) {
2809
+ // FIXME: Record this expression somewhere so that DI can perform the
2810
+ // initialization itself.
2811
+ Expr *initializer = nullptr ;
2812
+ typeCheckSynthesizedWrapperInitializer (pbd, backingVar, parentPBD,
2813
+ initializer);
2814
+ pbd->setInit (0 , initializer);
2815
+ pbd->setInitializerChecked (0 );
2816
+ } else if (var->hasObservers () && !dc->isTypeContext ()) {
2817
+ var->diagnose (diag::observingprop_requires_initializer);
2818
+ }
2815
2819
2816
- if (var->getOpaqueResultTypeDecl ()) {
2817
- var->diagnose (diag::opaque_type_var_no_underlying_type);
2820
+ if (var->getOpaqueResultTypeDecl ()) {
2821
+ var->diagnose (diag::opaque_type_var_no_underlying_type);
2822
+ }
2818
2823
}
2819
2824
}
2820
2825
2821
2826
// If there is a projection property (projectedValue) in the wrapper,
2822
2827
// synthesize a computed property for '$foo'.
2823
- VarDecl *storageVar = nullptr ;
2828
+ Expr *projectedValueInit = nullptr ;
2824
2829
if (wrapperInfo.projectedValueVar ) {
2825
- storageVar = synthesizePropertyWrapperProjectionVar (
2826
- ctx, var, storageInterfaceType, wrapperInfo.projectedValueVar );
2830
+ if (!projectionVar) {
2831
+ projectionVar = synthesizePropertyWrapperProjectionVar (ctx, var, storageInterfaceType,
2832
+ wrapperInfo.projectedValueVar );
2833
+ }
2834
+
2835
+ // Projected-value initialization is currently only supported for parameters.
2836
+ if (wrapperInfo.hasProjectedValueInit && isa<ParamDecl>(var)) {
2837
+ auto *param = dyn_cast<ParamDecl>(var);
2838
+ auto *placeholder = PropertyWrapperValuePlaceholderExpr::create (
2839
+ ctx, var->getSourceRange (), projectionVar->getType (), /* projectedValue=*/ nullptr );
2840
+ projectedValueInit = buildPropertyWrapperInitCall (var, backingVar->getType (),
2841
+ placeholder, PropertyWrapperInitKind::ProjectedValue);
2842
+ TypeChecker::typeCheckExpression (projectedValueInit, dc);
2843
+
2844
+ // Check initializer effects.
2845
+ auto *initContext = new (ctx) PropertyWrapperInitializer (
2846
+ dc, param, PropertyWrapperInitializer::Kind::ProjectedValue);
2847
+ TypeChecker::checkInitializerEffects (initContext, projectedValueInit);
2848
+ }
2827
2849
}
2828
2850
2829
2851
// If no initial wrapped value was provided via '=' and either:
@@ -2834,21 +2856,35 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
2834
2856
// value.
2835
2857
if (!wrappedValue && (!var->allAttachedPropertyWrappersHaveWrappedValueInit () ||
2836
2858
initializer)) {
2837
- return PropertyWrapperBackingPropertyInfo (backingVar, storageVar);
2859
+ return PropertyWrapperBackingPropertyInfo (backingVar, projectionVar, nullptr ,
2860
+ projectedValueInit);
2838
2861
}
2839
2862
2840
2863
// Form the initialization of the backing property from a value of the
2841
2864
// original property's type.
2842
- if (!initializer) {
2843
- initializer = PropertyWrapperValuePlaceholderExpr::create (
2865
+ Expr *wrappedValueInit = initializer;
2866
+ if (!wrappedValueInit) {
2867
+ wrappedValueInit = PropertyWrapperValuePlaceholderExpr::create (
2844
2868
ctx, var->getSourceRange (), var->getType (), /* wrappedValue=*/ nullptr );
2845
- typeCheckSynthesizedWrapperInitializer (
2846
- pbd, backingVar, parentPBD, initializer);
2869
+
2870
+ if (auto *param = dyn_cast<ParamDecl>(var)) {
2871
+ wrappedValueInit = buildPropertyWrapperInitCall (var, backingVar->getType (), wrappedValueInit,
2872
+ PropertyWrapperInitKind::WrappedValue);
2873
+ TypeChecker::typeCheckExpression (wrappedValueInit, dc);
2874
+
2875
+ // Check initializer effects.
2876
+ auto *initContext = new (ctx) PropertyWrapperInitializer (
2877
+ dc, param, PropertyWrapperInitializer::Kind::WrappedValue);
2878
+ TypeChecker::checkInitializerEffects (initContext, wrappedValueInit);
2879
+ } else {
2880
+ typeCheckSynthesizedWrapperInitializer (
2881
+ pbd, backingVar, var->getParentPatternBinding (), wrappedValueInit);
2882
+ }
2847
2883
}
2848
2884
2849
- return PropertyWrapperBackingPropertyInfo (backingVar, storageVar ,
2850
- /* wrappedValueInitExpr= */ initializer ,
2851
- /* projectedValueInitExpr= */ nullptr );
2885
+ return PropertyWrapperBackingPropertyInfo (backingVar, projectionVar ,
2886
+ wrappedValueInit ,
2887
+ projectedValueInit );
2852
2888
}
2853
2889
2854
2890
VarDecl *
0 commit comments