Skip to content

Commit dd82b63

Browse files
committed
Push VarDecl's TypeRepr into ParamDecl
VarDecls inherit their TypeRepr from their enclosing pattern, if any. To retrieve the TypeRepr attached to a VarDecl or a ParamDecl in a uniform way, the getTypeReprOrParentPatternTypeRepr API has been provided.
1 parent e4504af commit dd82b63

File tree

7 files changed

+48
-22
lines changed

7 files changed

+48
-22
lines changed

include/swift/AST/Decl.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4786,8 +4786,6 @@ class VarDecl : public AbstractStorageDecl {
47864786
bool issCaptureList, SourceLoc nameLoc, Identifier name,
47874787
DeclContext *dc, StorageIsMutable_t supportsMutation);
47884788

4789-
TypeRepr *ParentRepr = nullptr;
4790-
47914789
Type typeInContext;
47924790

47934791
public:
@@ -4806,11 +4804,6 @@ class VarDecl : public AbstractStorageDecl {
48064804
return hasName() ? getBaseName().getIdentifier().str() : "_";
48074805
}
48084806

4809-
/// Retrieve the TypeRepr corresponding to the parsed type of the parent
4810-
/// pattern, if it exists.
4811-
TypeRepr *getTypeRepr() const { return ParentRepr; }
4812-
void setTypeRepr(TypeRepr *repr) { ParentRepr = repr; }
4813-
48144807
bool hasType() const {
48154808
// We have a type if either the type has been computed already or if
48164809
// this is a deserialized declaration with an interface type.
@@ -4864,6 +4857,14 @@ class VarDecl : public AbstractStorageDecl {
48644857
///
48654858
Pattern *getParentPattern() const;
48664859

4860+
/// Returns the parsed type of this variable declaration. For parameters, this
4861+
/// is the parsed type the user explicitly wrote. For variables, this is the
4862+
/// type the user wrote in the typed pattern that binds this variable.
4863+
///
4864+
/// Note that there are many cases where the user may elide types. This will
4865+
/// return null in those cases.
4866+
TypeRepr *getTypeReprOrParentPatternTypeRepr() const;
4867+
48674868
/// Return the statement that owns the pattern associated with this VarDecl,
48684869
/// if one exists.
48694870
///
@@ -5158,6 +5159,8 @@ class ParamDecl : public VarDecl {
51585159
SourceLoc ArgumentNameLoc;
51595160
SourceLoc SpecifierLoc;
51605161

5162+
TypeRepr *TyRepr = nullptr;
5163+
51615164
struct StoredDefaultArgument {
51625165
PointerUnion<Expr *, VarDecl *> DefaultArg;
51635166
Initializer *InitContext = nullptr;
@@ -5203,6 +5206,10 @@ class ParamDecl : public VarDecl {
52035206

52045207
SourceLoc getSpecifierLoc() const { return SpecifierLoc; }
52055208

5209+
/// Retrieve the TypeRepr corresponding to the parsed type of the parameter, if it exists.
5210+
TypeRepr *getTypeRepr() const { return TyRepr; }
5211+
void setTypeRepr(TypeRepr *repr) { TyRepr = repr; }
5212+
52065213
DefaultArgumentKind getDefaultArgumentKind() const {
52075214
return static_cast<DefaultArgumentKind>(Bits.ParamDecl.defaultArgumentKind);
52085215
}

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2524,7 +2524,7 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
25242524
if (decl->hasInterfaceType()) {
25252525
Printer << ": ";
25262526
TypeLoc tyLoc;
2527-
if (auto *repr = decl->getTypeRepr())
2527+
if (auto *repr = decl->getTypeReprOrParentPatternTypeRepr())
25282528
tyLoc = TypeLoc(repr, decl->getInterfaceType());
25292529
else
25302530
tyLoc = TypeLoc::withoutLoc(decl->getInterfaceType());

lib/AST/Decl.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2595,7 +2595,7 @@ OpaqueReturnTypeRepr *ValueDecl::getOpaqueResultTypeRepr() const {
25952595
}
25962596
}
25972597
} else {
2598-
returnRepr = VD->getTypeRepr();
2598+
returnRepr = VD->getTypeReprOrParentPatternTypeRepr();
25992599
}
26002600
} else if (auto *FD = dyn_cast<FuncDecl>(this)) {
26012601
returnRepr = FD->getBodyResultTypeLoc().getTypeRepr();
@@ -5285,6 +5285,16 @@ Pattern *VarDecl::getParentPattern() const {
52855285
return nullptr;
52865286
}
52875287

5288+
TypeRepr *VarDecl::getTypeReprOrParentPatternTypeRepr() const {
5289+
if (auto *param = dyn_cast<ParamDecl>(this))
5290+
return param->getTypeRepr();
5291+
5292+
if (auto *parentPattern = dyn_cast_or_null<TypedPattern>(getParentPattern()))
5293+
return parentPattern->getTypeLoc().getTypeRepr();
5294+
5295+
return nullptr;
5296+
}
5297+
52885298
NullablePtr<VarDecl>
52895299
VarDecl::getCorrespondingFirstCaseLabelItemVarDecl() const {
52905300
if (!hasName())

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2136,8 +2136,10 @@ class FallbackDiagnosticListener : public ExprTypeCheckListener {
21362136
// Before producing fatal error here, let's check if there are any "error"
21372137
// diagnostics already emitted or waiting to be emitted. Because they are
21382138
// a better indication of the problem.
2139-
if (!(hadAnyErrors() || TC.Context.hasDelayedConformanceErrors()))
2139+
if (!(hadAnyErrors() || TC.Context.hasDelayedConformanceErrors())) {
21402140
TC.diagnose(expr->getLoc(), diag::failed_to_produce_diagnostic);
2141+
llvm_unreachable("");
2142+
}
21412143
}
21422144
};
21432145

lib/Sema/TypeCheckDecl.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3663,7 +3663,7 @@ IsImplicitlyUnwrappedOptionalRequest::evaluate(Evaluator &evaluator,
36633663
if (auto *subscript = dyn_cast<SubscriptDecl>(storage))
36643664
TyR = subscript->getElementTypeLoc().getTypeRepr();
36653665
else
3666-
TyR = cast<VarDecl>(storage)->getTypeRepr();
3666+
TyR = cast<VarDecl>(storage)->getTypeReprOrParentPatternTypeRepr();
36673667
break;
36683668
}
36693669

@@ -4251,21 +4251,26 @@ void TypeChecker::validateDecl(ValueDecl *D) {
42514251
break;
42524252
}
42534253

4254-
// If we're already checking our PatternBindingDecl, bail out
4255-
// without setting our own 'is being validated' flag, since we
4256-
// will attempt validation again later.
4257-
if (PBD->isBeingValidated())
4258-
return;
4259-
4260-
// Attempt to infer the type using initializer expressions.
4261-
validatePatternBindingEntries(*this, PBD);
4254+
// If we're not being validated, validate our parent pattern binding and
4255+
// attempt to infer the interface type using the initializer expressions.
4256+
if (!PBD->isBeingValidated()) {
4257+
validatePatternBindingEntries(*this, PBD);
4258+
}
42624259

42634260
auto parentPattern = VD->getParentPattern();
42644261
if (PBD->isInvalid() || !parentPattern->hasType()) {
42654262
parentPattern->setType(ErrorType::get(Context));
42664263
setBoundVarsTypeError(parentPattern, Context);
42674264
}
42684265

4266+
auto interfaceType = parentPattern->getType()->mapTypeOutOfContext();
4267+
// In SIL mode, VarDecls are written as having reference storage types.
4268+
if (!interfaceType->is<ReferenceStorageType>()) {
4269+
if (auto *attr = VD->getAttrs().getAttribute<ReferenceOwnershipAttr>())
4270+
interfaceType = checkReferenceOwnershipAttr(VD, interfaceType, attr);
4271+
}
4272+
VD->setInterfaceType(interfaceType);
4273+
42694274
break;
42704275
}
42714276

lib/Sema/TypeCheckPattern.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,9 +1013,11 @@ bool TypeChecker::coercePatternToType(Pattern *&P, TypeResolution resolution,
10131013

10141014
// Note that the pattern's type does not include the reference storage type.
10151015
P->setType(type);
1016-
var->setInterfaceType(interfaceType);
10171016
var->setType(var->getDeclContext()->mapTypeIntoContext(interfaceType));
1018-
var->setTypeRepr(tyLoc.getTypeRepr());
1017+
// If there's no parent pattern binding then take this opportunity to
1018+
// set the interface type as well.
1019+
if (var->getParentPatternBinding() == nullptr)
1020+
var->setInterfaceType(interfaceType);
10191021

10201022
// FIXME: Should probably just remove the forbidden prefix stuff, it no
10211023
// longer makes a lot of sense in a request-based world.

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2421,7 +2421,7 @@ static void finishProtocolStorageImplInfo(AbstractStorageDecl *storage,
24212421
StorageImplInfo &info) {
24222422
if (auto *var = dyn_cast<VarDecl>(storage)) {
24232423
SourceLoc typeLoc;
2424-
if (auto *repr = var->getTypeRepr())
2424+
if (auto *repr = var->getTypeReprOrParentPatternTypeRepr())
24252425
typeLoc = repr->getLoc();
24262426

24272427
if (info.hasStorage()) {

0 commit comments

Comments
 (0)