Skip to content

Commit 2af662b

Browse files
authored
Merge pull request #4042 from slavapestov/sundry-sema-fixes
2 parents 045bc16 + e354ecf commit 2af662b

19 files changed

+135
-138
lines changed

include/swift/AST/Decl.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,6 @@ class alignas(1 << DeclAlignInBits) Decl {
288288
/// once (either in its declaration, or once later), making it immutable.
289289
unsigned IsLet : 1;
290290

291-
/// \brief Whether this is an 'inout' parameter; this is preferable
292-
/// to checking if the parameter type is an InOutType, because invalid
293-
/// inout parameters have an error type.
294-
unsigned IsInOut : 1;
295-
296291
/// \brief Whether this vardecl has an initial value bound to it in a way
297292
/// that isn't represented in the AST with an initializer in the pattern
298293
/// binding. This happens in cases like "for i in ...", switch cases, etc.
@@ -306,7 +301,7 @@ class alignas(1 << DeclAlignInBits) Decl {
306301
/// a.storage for lazy var a is a decl that cannot be accessed.
307302
unsigned IsUserAccessible : 1;
308303
};
309-
enum { NumVarDeclBits = NumAbstractStorageDeclBits + 6 };
304+
enum { NumVarDeclBits = NumAbstractStorageDeclBits + 5 };
310305
static_assert(NumVarDeclBits <= 32, "fits in an unsigned");
311306

312307
class EnumElementDeclBitfields {
@@ -4250,7 +4245,6 @@ class VarDecl : public AbstractStorageDecl {
42504245
VarDeclBits.IsUserAccessible = true;
42514246
VarDeclBits.IsStatic = IsStatic;
42524247
VarDeclBits.IsLet = IsLet;
4253-
VarDeclBits.IsInOut = false;
42544248
VarDeclBits.IsDebuggerVar = false;
42554249
VarDeclBits.HasNonPatternBindingInit = false;
42564250
setType(Ty);
@@ -4348,10 +4342,6 @@ class VarDecl : public AbstractStorageDecl {
43484342
bool isLet() const { return VarDeclBits.IsLet; }
43494343
void setLet(bool IsLet) { VarDeclBits.IsLet = IsLet; }
43504344

4351-
/// Is this an 'inout' parameter?
4352-
bool isInOut() const { return VarDeclBits.IsInOut; }
4353-
void setInOut(bool InOut) { VarDeclBits.IsInOut = InOut; }
4354-
43554345
/// Return true if this vardecl has an initial value bound to it in a way
43564346
/// that isn't represented in the AST with an initializer in the pattern
43574347
/// binding. This happens in cases like "for i in ...", switch cases, etc.

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ ERROR(could_not_use_type_member_on_instance,none,
9696
ERROR(could_not_use_enum_element_on_instance,none,
9797
"enum element %0 cannot be referenced as an instance member",
9898
(DeclName))
99-
ERROR(could_not_use_type_member_on_existential,none,
99+
ERROR(could_not_use_type_member_on_protocol_metatype,none,
100100
"static member %1 cannot be used on protocol metatype %0",
101101
(Type, DeclName))
102102
ERROR(could_not_use_instance_member_on_type,none,

lib/AST/NameLookup.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -556,15 +556,8 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
556556

557557
SmallVector<ValueDecl *, 4> Lookup;
558558
DC->lookupQualified(ExtendedType, Name, options, TypeResolver, Lookup);
559-
bool isMetatypeType = ExtendedType->is<AnyMetatypeType>();
560559
bool FoundAny = false;
561560
for (auto Result : Lookup) {
562-
// If we're looking into an instance, skip static functions.
563-
if (!isMetatypeType &&
564-
isa<FuncDecl>(Result) &&
565-
cast<FuncDecl>(Result)->isStatic())
566-
continue;
567-
568561
// Classify this declaration.
569562
FoundAny = true;
570563

@@ -575,12 +568,6 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
575568
else
576569
Results.push_back(UnqualifiedLookupResult(MetaBaseDecl, Result));
577570
continue;
578-
} else if (auto FD = dyn_cast<FuncDecl>(Result)) {
579-
if (FD->isStatic() && !isMetatypeType)
580-
continue;
581-
} else if (isa<EnumElementDecl>(Result)) {
582-
Results.push_back(UnqualifiedLookupResult(BaseDecl, Result));
583-
continue;
584571
}
585572

586573
Results.push_back(UnqualifiedLookupResult(BaseDecl, Result));

lib/Parse/ParsePattern.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,10 +387,8 @@ mapParsedParameters(Parser &parser,
387387
// If a type was provided, create the type for the parameter.
388388
if (auto type = paramInfo.Type) {
389389
// If 'inout' was specified, turn the type into an in-out type.
390-
if (specifierKind == Parser::ParsedParameter::InOut) {
390+
if (specifierKind == Parser::ParsedParameter::InOut)
391391
type = new (ctx) InOutTypeRepr(type, paramInfo.LetVarInOutLoc);
392-
param->setInOut(true);
393-
}
394392

395393
param->getTypeLoc() = TypeLoc(type);
396394
} else if (paramContext != Parser::ParameterContextKind::Closure) {

lib/Sema/CSApply.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3388,7 +3388,13 @@ namespace {
33883388
}
33893389

33903390
Expr *visitUnresolvedPatternExpr(UnresolvedPatternExpr *expr) {
3391-
llvm_unreachable("should have been eliminated during name binding");
3391+
// If we end up here, we should have diagnosed somewhere else
3392+
// already.
3393+
if (!SuppressDiagnostics) {
3394+
cs.TC.diagnose(expr->getLoc(), diag::pattern_in_expr,
3395+
expr->getSubPattern()->getKind());
3396+
}
3397+
return expr;
33923398
}
33933399

33943400
Expr *visitBindOptionalExpr(BindOptionalExpr *expr) {

lib/Sema/CSDiag.cpp

Lines changed: 76 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,10 +1948,13 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
19481948
/// the exact expression kind).
19491949
bool diagnoseGeneralMemberFailure(Constraint *constraint);
19501950

1951-
/// Diagnose the lookup of an enum element as instance member where only a
1952-
/// static member is allowed
1953-
void diagnoseEnumInstanceMemberLookup(EnumElementDecl *enumElementDecl,
1954-
SourceLoc loc);
1951+
/// Diagnose the lookup of an static member or enum element as instance member.
1952+
void diagnoseTypeMemberOnInstanceLookup(Type baseObjTy,
1953+
Expr *baseExpr,
1954+
DeclName memberName,
1955+
DeclNameLoc nameLoc,
1956+
ValueDecl *member,
1957+
SourceLoc loc);
19551958

19561959
/// Given a result of name lookup that had no viable results, diagnose the
19571960
/// unviable ones.
@@ -2338,12 +2341,54 @@ bool FailureDiagnosis::diagnoseGeneralMemberFailure(Constraint *constraint) {
23382341
}
23392342

23402343
void FailureDiagnosis::
2341-
diagnoseEnumInstanceMemberLookup(EnumElementDecl *enumElementDecl,
2342-
SourceLoc loc) {
2343-
auto diag = diagnose(loc, diag::could_not_use_enum_element_on_instance,
2344-
enumElementDecl->getName());
2345-
auto parentEnum = enumElementDecl->getParentEnum();
2346-
auto enumMetatype = parentEnum->getType()->castTo<AnyMetatypeType>();
2344+
diagnoseTypeMemberOnInstanceLookup(Type baseObjTy,
2345+
Expr *baseExpr,
2346+
DeclName memberName,
2347+
DeclNameLoc nameLoc,
2348+
ValueDecl *member,
2349+
SourceLoc loc) {
2350+
SourceRange baseRange = baseExpr ? baseExpr->getSourceRange() : SourceRange();
2351+
2352+
// If the base of the lookup is a protocol metatype, suggest
2353+
// to replace the metatype with 'Self'
2354+
// error saying the lookup cannot be on a protocol metatype
2355+
if (auto metatypeTy = baseObjTy->getAs<MetatypeType>()) {
2356+
auto Diag = diagnose(loc,
2357+
diag::could_not_use_type_member_on_protocol_metatype,
2358+
baseObjTy, memberName);
2359+
Diag.highlight(baseRange).highlight(nameLoc.getSourceRange());
2360+
2361+
// See through function decl context
2362+
if (auto parent = CS->DC->getInnermostTypeContext()) {
2363+
// If we are in a protocol extension of 'Proto' and we see
2364+
// 'Proto.static', suggest 'Self.static'
2365+
if (auto extensionContext = parent->getAsProtocolExtensionContext()) {
2366+
if (extensionContext->getDeclaredType()->getCanonicalType()
2367+
== metatypeTy->getInstanceType()->getCanonicalType()) {
2368+
Diag.fixItReplace(baseRange, "Self");
2369+
}
2370+
}
2371+
}
2372+
2373+
return;
2374+
}
2375+
2376+
// Otherwise the static member lookup was invalid because it was
2377+
// called on an instance
2378+
Optional<InFlightDiagnostic> Diag;
2379+
2380+
if (isa<EnumElementDecl>(member))
2381+
Diag.emplace(diagnose(loc, diag::could_not_use_enum_element_on_instance,
2382+
memberName));
2383+
else
2384+
Diag.emplace(diagnose(loc, diag::could_not_use_type_member_on_instance,
2385+
baseObjTy, memberName));
2386+
2387+
Diag->highlight(nameLoc.getSourceRange());
2388+
2389+
// No fix-it if the lookup was qualified
2390+
if (baseExpr && !baseExpr->isImplicit())
2391+
return;
23472392

23482393
// Determine the contextual type of the expression
23492394
Type contextualType;
@@ -2355,8 +2400,8 @@ diagnoseEnumInstanceMemberLookup(EnumElementDecl *enumElementDecl,
23552400

23562401
// Try to provide a fix-it that only contains a '.'
23572402
if (contextualType) {
2358-
if (enumMetatype->getInstanceType()->isEqual(contextualType)) {
2359-
diag.fixItInsert(loc, ".");
2403+
if (baseObjTy->isEqual(contextualType)) {
2404+
Diag->fixItInsert(loc, ".");
23602405
return;
23612406
}
23622407
}
@@ -2382,8 +2427,8 @@ diagnoseEnumInstanceMemberLookup(EnumElementDecl *enumElementDecl,
23822427
// If the rhs of '~=' is the enum type, a single dot suffixes
23832428
// since the type can be inferred
23842429
Type secondArgType = binaryExpr->getArg()->getElement(1)->getType();
2385-
if (secondArgType->isEqual(enumMetatype->getInstanceType())) {
2386-
diag.fixItInsert(loc, ".");
2430+
if (secondArgType->isEqual(baseObjTy)) {
2431+
Diag->fixItInsert(loc, ".");
23872432
return;
23882433
}
23892434
}
@@ -2392,12 +2437,14 @@ diagnoseEnumInstanceMemberLookup(EnumElementDecl *enumElementDecl,
23922437
}
23932438

23942439
// Fall back to a fix-it with a full type qualifier
2395-
SmallString<32> enumTypeName;
2396-
llvm::raw_svector_ostream typeNameStream(enumTypeName);
2397-
typeNameStream << parentEnum->getName();
2398-
typeNameStream << ".";
2399-
2400-
diag.fixItInsert(loc, typeNameStream.str());
2440+
auto nominal =
2441+
member->getDeclContext()
2442+
->getAsNominalTypeOrNominalTypeExtensionContext();
2443+
SmallString<32> typeName;
2444+
llvm::raw_svector_ostream typeNameStream(typeName);
2445+
typeNameStream << nominal->getName() << ".";
2446+
2447+
Diag->fixItInsert(loc, typeNameStream.str());
24012448
return;
24022449
}
24032450

@@ -2461,8 +2508,12 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
24612508
// because there is exactly one candidate!) diagnose this.
24622509
bool sameProblem = true;
24632510
auto firstProblem = result.UnviableCandidates[0].second;
2464-
for (auto cand : result.UnviableCandidates)
2511+
ValueDecl *member = nullptr;
2512+
for (auto cand : result.UnviableCandidates) {
2513+
if (member == nullptr)
2514+
member = cand.first;
24652515
sameProblem &= cand.second == firstProblem;
2516+
}
24662517

24672518
auto instanceTy = baseObjTy;
24682519
if (auto *MTT = instanceTy->getAs<AnyMetatypeType>())
@@ -2527,48 +2578,11 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
25272578
instanceTy, memberName)
25282579
.highlight(baseRange).highlight(nameLoc.getSourceRange());
25292580
return;
2530-
2531-
case MemberLookupResult::UR_TypeMemberOnInstance:
2532-
if (instanceTy->isExistentialType() && baseObjTy->is<AnyMetatypeType>()) {
2533-
// If the base of the lookup is an existential metatype, emit an
2534-
// error saying the lookup cannot be on a protocol metatype
2535-
auto Diag = diagnose(loc, diag::could_not_use_type_member_on_existential,
2536-
baseObjTy, memberName);
2537-
Diag.highlight(baseRange).highlight(nameLoc.getSourceRange());
2538-
2539-
// See through function decl context
2540-
if (auto parent = CS->DC->getParent())
2541-
// If we are in a protocol extension of 'Proto' and we see
2542-
// 'Proto.static', suggest 'Self.static'
2543-
if (auto extensionContext = parent->getAsProtocolExtensionContext()) {
2544-
if (extensionContext->getDeclaredType()->getCanonicalType()
2545-
== instanceTy->getCanonicalType()) {
2546-
Diag.fixItReplace(baseRange, "Self");
2547-
}
2548-
}
25492581

2550-
} else {
2551-
// Otherwise the static member lookup was invalid because it was
2552-
// called on an instance
2553-
2554-
// Handle enum element lookup on instance type
2555-
auto lookThroughBaseObjTy = baseObjTy->lookThroughAllAnyOptionalTypes();
2556-
if (lookThroughBaseObjTy->is<EnumType>()
2557-
|| lookThroughBaseObjTy->is<BoundGenericEnumType>()) {
2558-
for (auto cand : result.UnviableCandidates) {
2559-
ValueDecl *decl = cand.first;
2560-
if (auto enumElementDecl = dyn_cast<EnumElementDecl>(decl)) {
2561-
diagnoseEnumInstanceMemberLookup(enumElementDecl, loc);
2562-
return;
2563-
}
2564-
}
2565-
}
2566-
2567-
// Provide diagnostic other static member lookups on instance type
2568-
diagnose(loc, diag::could_not_use_type_member_on_instance,
2569-
baseObjTy, memberName)
2570-
.highlight(baseRange).highlight(nameLoc.getSourceRange());
2571-
}
2582+
case MemberLookupResult::UR_TypeMemberOnInstance:
2583+
diagnoseTypeMemberOnInstanceLookup(baseObjTy, baseExpr,
2584+
memberName, nameLoc,
2585+
member, loc);
25722586
return;
25732587

25742588
case MemberLookupResult::UR_MutatingMemberOnRValue:

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2627,9 +2627,7 @@ namespace {
26272627
Type visitUnresolvedPatternExpr(UnresolvedPatternExpr *expr) {
26282628
// If there are UnresolvedPatterns floating around after name binding,
26292629
// they are pattern productions in invalid positions.
2630-
CS.TC.diagnose(expr->getLoc(), diag::pattern_in_expr,
2631-
expr->getSubPattern()->getKind());
2632-
return Type();
2630+
return ErrorType::get(CS.getASTContext());
26332631
}
26342632

26352633
/// Get the type T?

lib/Sema/TypeCheckDecl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,6 @@ Type swift::configureImplicitSelf(TypeChecker &tc,
11211121
// 'self' is 'let' for reference types (i.e., classes) or when 'self' is
11221122
// neither inout.
11231123
selfDecl->setLet(!selfTy->is<InOutType>());
1124-
selfDecl->setInOut(selfTy->is<InOutType>());
11251124
selfDecl->overwriteType(selfTy);
11261125

11271126
// Install the self type on the Parameter that contains it. This ensures that

0 commit comments

Comments
 (0)