@@ -2856,52 +2856,64 @@ bool TypeChecker::isSubstitutableFor(Type type, ArchetypeType *archetype,
2856
2856
return true ;
2857
2857
}
2858
2858
2859
- Expr *TypeChecker::coerceToRValue (Expr *expr) {
2859
+ Expr *TypeChecker::coerceToRValue (Expr *expr,
2860
+ llvm::function_ref<Type(Expr *)> getType,
2861
+ llvm::function_ref<void(Expr *, Type)> setType) {
2862
+ Type exprTy = getType (expr);
2863
+
2860
2864
// If expr has no type, just assume it's the right expr.
2861
- if (!expr-> getType () )
2865
+ if (!exprTy )
2862
2866
return expr;
2863
-
2864
- Type exprTy = expr->getType ();
2865
-
2867
+
2866
2868
// If the type is already materializable, then we're already done.
2867
2869
if (!exprTy->hasLValueType ())
2868
2870
return expr;
2869
2871
2870
2872
// Load lvalues.
2871
2873
if (auto lvalue = exprTy->getAs <LValueType>()) {
2872
2874
expr->propagateLValueAccessKind (AccessKind::Read);
2873
- return new (Context) LoadExpr (expr, lvalue->getObjectType ());
2875
+ auto result = new (Context) LoadExpr (expr, lvalue->getObjectType ());
2876
+ setType (result, lvalue->getObjectType ());
2877
+ return result;
2874
2878
}
2875
2879
2876
2880
// Walk into parenthesized expressions to update the subexpression.
2877
2881
if (auto paren = dyn_cast<IdentityExpr>(expr)) {
2878
- auto sub = coerceToRValue (paren->getSubExpr ());
2882
+ auto sub = coerceToRValue (paren->getSubExpr (), getType, setType );
2879
2883
paren->setSubExpr (sub);
2880
- paren-> setType (sub-> getType ());
2884
+ setType (paren, getType (sub ));
2881
2885
return paren;
2882
2886
}
2883
2887
2884
2888
// Walk into 'try' and 'try!' expressions to update the subexpression.
2885
2889
if (auto tryExpr = dyn_cast<AnyTryExpr>(expr)) {
2886
- auto sub = coerceToRValue (tryExpr->getSubExpr ());
2890
+ auto sub = coerceToRValue (tryExpr->getSubExpr (), getType, setType );
2887
2891
tryExpr->setSubExpr (sub);
2888
- if (isa<OptionalTryExpr>(tryExpr) && !sub-> getType ()->hasError ())
2889
- tryExpr-> setType (OptionalType::get (sub-> getType ()));
2892
+ if (isa<OptionalTryExpr>(tryExpr) && !getType (sub )->hasError ())
2893
+ setType (tryExpr, OptionalType::get (getType (sub )));
2890
2894
else
2891
- tryExpr-> setType (sub-> getType ());
2895
+ setType (tryExpr, getType (sub ));
2892
2896
return tryExpr;
2893
2897
}
2894
2898
2899
+ // Can't load from an inout value.
2900
+ if (auto inoutExpr = dyn_cast<InOutExpr>(expr)) {
2901
+ diagnose (expr->getLoc (), diag::load_of_explicit_lvalue,
2902
+ exprTy->castTo <InOutType>()->getObjectType ())
2903
+ .fixItRemove (SourceRange (inoutExpr->getLoc ()));
2904
+ return coerceToRValue (inoutExpr->getSubExpr (), getType, setType);
2905
+ }
2906
+
2895
2907
// Walk into tuples to update the subexpressions.
2896
2908
if (auto tuple = dyn_cast<TupleExpr>(expr)) {
2897
2909
bool anyChanged = false ;
2898
2910
for (auto &elt : tuple->getElements ()) {
2899
2911
// Materialize the element.
2900
- auto oldType = elt-> getType ();
2901
- elt = coerceToRValue (elt);
2912
+ auto oldType = getType (elt );
2913
+ elt = coerceToRValue (elt, getType, setType );
2902
2914
2903
2915
// If the type changed at all, make a note of it.
2904
- if (elt-> getType ().getPointer () != oldType.getPointer ()) {
2916
+ if (getType (elt ).getPointer () != oldType.getPointer ()) {
2905
2917
anyChanged = true ;
2906
2918
}
2907
2919
}
@@ -2911,11 +2923,11 @@ Expr *TypeChecker::coerceToRValue(Expr *expr) {
2911
2923
SmallVector<TupleTypeElt, 4 > elements;
2912
2924
elements.reserve (tuple->getElements ().size ());
2913
2925
for (unsigned i = 0 , n = tuple->getNumElements (); i != n; ++i) {
2914
- Type type = tuple->getElement (i)-> getType ( );
2926
+ Type type = getType ( tuple->getElement (i));
2915
2927
Identifier name = tuple->getElementName (i);
2916
2928
elements.push_back (TupleTypeElt (type, name));
2917
2929
}
2918
- tuple-> setType (TupleType::get (elements, Context));
2930
+ setType (tuple, TupleType::get (elements, Context));
2919
2931
}
2920
2932
2921
2933
return tuple;
0 commit comments