Skip to content

Commit 456d91f

Browse files
authored
Merge pull request #6412 from slavapestov/more-small-sema-fixes
More small Sema fixes
2 parents 0ac2371 + 1cb6563 commit 456d91f

File tree

43 files changed

+233
-131
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+233
-131
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1789,7 +1789,7 @@ ERROR(raw_type_not_literal_convertible,none,
17891789
"raw type %0 is not expressible by any literal",
17901790
(Type))
17911791
ERROR(enum_raw_type_not_equatable,none,
1792-
"RawRepresentable 'init' cannot be synthesized because raw type %0 is not "
1792+
"RawRepresentable conformance cannot be synthesized because raw type %0 is not "
17931793
"Equatable", (Type))
17941794
ERROR(enum_raw_type_nonconforming_and_nonsynthable,none,
17951795
"%0 declares raw type %1, but does not conform to RawRepresentable "

include/swift/AST/LazyResolver.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,6 @@ class LazyResolver {
5757
const NormalProtocolConformance *conformance,
5858
ProtocolDecl *inherited) = 0;
5959

60-
/// Resolve a member type.
61-
///
62-
/// \param dc The context in which to resolve the type.
63-
/// \param type The type in which we will search for the member type.
64-
/// \param name The name of the member type.
65-
///
66-
/// \returns the member type, or an empty type if no such type could be
67-
/// found.
68-
virtual Type resolveMemberType(DeclContext *dc, Type type,
69-
Identifier name) = 0;
70-
7160
/// Resolve the accessibility of a value.
7261
///
7362
/// It does no type-checking.
@@ -144,10 +133,6 @@ class DelegatingLazyResolver : public LazyResolver {
144133
return Principal.resolveInheritedConformance(conformance, inherited);
145134
}
146135

147-
Type resolveMemberType(DeclContext *dc, Type type, Identifier name) override {
148-
return Principal.resolveMemberType(dc, type, name);
149-
}
150-
151136
void resolveAccessibility(ValueDecl *VD) override {
152137
Principal.resolveAccessibility(VD);
153138
}

lib/AST/Decl.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -796,16 +796,13 @@ ExtensionDecl::takeConformanceLoaderSlow() {
796796
}
797797

798798
bool ExtensionDecl::isConstrainedExtension() const {
799-
auto nominal = getExtendedType()->getAnyNominal();
800-
801-
// Error case: erroneous extension.
802-
if (!nominal)
803-
return false;
804-
805799
// Non-generic extension.
806800
if (!getGenericSignature())
807801
return false;
808802

803+
auto nominal = getExtendedType()->getAnyNominal();
804+
assert(nominal);
805+
809806
// If the generic signature differs from that of the nominal type, it's a
810807
// constrained extension.
811808
return getGenericSignature()->getCanonicalSignature()

lib/AST/DeclContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ bool DeclContext::walkContext(ASTWalker &Walker) {
667667
}
668668

669669
void DeclContext::dumpContext() const {
670-
printContext(llvm::outs());
670+
printContext(llvm::errs());
671671
}
672672

673673
template <typename DCType>
@@ -728,7 +728,7 @@ unsigned DeclContext::printContext(raw_ostream &OS, unsigned indent) const {
728728
case DeclContextKind::AbstractFunctionDecl:
729729
Kind = "AbstractFunctionDecl";
730730
break;
731-
case DeclContextKind::SubscriptDecl: Kind = "SubscriptDecl"; break;
731+
case DeclContextKind::SubscriptDecl: Kind = "SubscriptDecl"; break;
732732
}
733733
OS.indent(Depth*2 + indent) << "0x" << (void*)this << " " << Kind;
734734

lib/AST/LookupVisibleDecls.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ static void doDynamicLookup(VisibleDeclConsumer &Consumer,
337337
assert(FD->getImplicitSelfDecl() && "should not find free functions");
338338
(void)FD;
339339

340+
if (FD->isInvalid())
341+
break;
342+
340343
// Get the type without the first uncurry level with 'self'.
341344
CanType T = D->getInterfaceType()
342345
->castTo<AnyFunctionType>()

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6895,11 +6895,12 @@ Expr *ConstraintSystem::applySolutionShallow(const Solution &solution,
68956895
Expr *Solution::coerceToType(Expr *expr, Type toType,
68966896
ConstraintLocator *locator,
68976897
bool ignoreTopLevelInjection,
6898+
bool skipClosures,
68986899
Optional<Pattern*> typeFromPattern) const {
68996900
auto &cs = getConstraintSystem();
69006901
ExprRewriter rewriter(cs, *this,
69016902
/*suppressDiagnostics=*/false,
6902-
/*skipClosures=*/false);
6903+
/*skipClosures=*/skipClosures);
69036904
Expr *result = rewriter.coerceToType(expr, toType, locator, typeFromPattern);
69046905
if (!result)
69056906
return nullptr;

lib/Sema/CSDiag.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3235,7 +3235,8 @@ namespace {
32353235

32363236
if (!PossiblyInvalidDecls.empty())
32373237
for (auto D : PossiblyInvalidDecls)
3238-
D->setInvalid(D->getInterfaceType()->hasError());
3238+
if (D->hasInterfaceType())
3239+
D->setInvalid(D->getInterfaceType()->hasError());
32393240

32403241
// Done, don't do redundant work on destruction.
32413242
ExprTypes.clear();
@@ -3279,7 +3280,8 @@ namespace {
32793280

32803281
if (!PossiblyInvalidDecls.empty())
32813282
for (auto D : PossiblyInvalidDecls)
3282-
D->setInvalid(D->getInterfaceType()->hasError());
3283+
if (D->hasInterfaceType())
3284+
D->setInvalid(D->getInterfaceType()->hasError());
32833285
}
32843286
};
32853287
} // end anonymous namespace
@@ -7042,7 +7044,7 @@ static void noteArchetypeSource(const TypeLoc &loc, ArchetypeType *archetype,
70427044
if (auto ident = dyn_cast<ComponentIdentTypeRepr>(T)) {
70437045
auto *generic =
70447046
dyn_cast_or_null<GenericTypeDecl>(ident->getBoundDecl());
7045-
if (hasArchetype(generic, Archetype)) {
7047+
if (generic && hasArchetype(generic, Archetype)) {
70467048
FoundDecl = generic;
70477049
FoundGenericTypeBase = ident;
70487050
return false;

lib/Sema/ConstraintSystem.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,13 +566,17 @@ class Solution {
566566
/// on a suspicious top-level optional injection (because the caller already
567567
/// diagnosed it).
568568
///
569+
/// \param skipClosures Whether to skip bodies of non-single expression
570+
/// closures.
571+
///
569572
/// \param typeFromPattern Optionally, the caller can specify the pattern
570573
/// from where the toType is derived, so that we can deliver better fixit.
571574
///
572575
/// \returns the coerced expression, which will have type \c ToType.
573576
Expr *coerceToType(Expr *expr, Type toType,
574577
ConstraintLocator *locator,
575578
bool ignoreTopLevelInjection = false,
579+
bool skipClosures = false,
576580
Optional<Pattern*> typeFromPattern = None) const;
577581

578582
/// \brief Convert the given expression to a logic value.

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
327327
return initDecl;
328328
}
329329

330-
static bool canSynthesizeRawRepresentable(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
330+
static bool canSynthesizeRawRepresentable(TypeChecker &tc, Decl *parentDecl,
331+
EnumDecl *enumDecl) {
331332

332333
// It must have a valid raw type.
333334
Type rawType = enumDecl->getRawType();
@@ -340,17 +341,15 @@ static bool canSynthesizeRawRepresentable(TypeChecker &tc, Decl *parentDecl, Enu
340341
enumDecl->getInherited().front().isError())
341342
return false;
342343

343-
// The raw type must be Equatable, so that we have a suitable ~= for synthesized switch statements.
344+
// The raw type must be Equatable, so that we have a suitable ~= for
345+
// synthesized switch statements.
344346
auto equatableProto = tc.getProtocol(enumDecl->getLoc(),
345347
KnownProtocolKind::Equatable);
346348
if (!equatableProto)
347349
return false;
348350

349-
if (!tc.conformsToProtocol(rawType, equatableProto, enumDecl, None)) {
350-
SourceLoc loc = enumDecl->getInherited()[0].getSourceRange().Start;
351-
tc.diagnose(loc, diag::enum_raw_type_not_equatable, rawType);
351+
if (!tc.conformsToProtocol(rawType, equatableProto, enumDecl, None))
352352
return false;
353-
}
354353

355354
// There must be enum elements.
356355
if (enumDecl->getAllElements().empty())

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,13 +1810,14 @@ bool TypeChecker::typeCheckExpressionShallow(Expr *&expr, DeclContext *dc) {
18101810
}
18111811

18121812
bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
1813-
DeclContext *DC) {
1813+
DeclContext *DC, bool skipClosures) {
18141814

18151815
/// Type checking listener for pattern binding initializers.
18161816
class BindingListener : public ExprTypeCheckListener {
18171817
Pattern *&pattern;
18181818
Expr *&initializer;
18191819
DeclContext *DC;
1820+
bool skipClosures;
18201821

18211822
/// The locator we're using.
18221823
ConstraintLocator *Locator;
@@ -1826,8 +1827,9 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
18261827

18271828
public:
18281829
explicit BindingListener(Pattern *&pattern, Expr *&initializer,
1829-
DeclContext *DC)
1830-
: pattern(pattern), initializer(initializer), DC(DC) { }
1830+
DeclContext *DC, bool skipClosures)
1831+
: pattern(pattern), initializer(initializer), DC(DC),
1832+
skipClosures(skipClosures) { }
18311833

18321834
bool builtConstraints(ConstraintSystem &cs, Expr *expr) override {
18331835
// Save the locator we're using for the expression.
@@ -1855,7 +1857,8 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
18551857
// Convert the initializer to the type of the pattern.
18561858
// ignoreTopLevelInjection = Binding->isConditional()
18571859
expr = solution.coerceToType(expr, InitType, Locator,
1858-
false /* ignoreTopLevelInjection */);
1860+
false /* ignoreTopLevelInjection */,
1861+
skipClosures);
18591862
if (!expr) {
18601863
return nullptr;
18611864
}
@@ -1882,7 +1885,7 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
18821885
};
18831886

18841887
assert(initializer && "type-checking an uninitialized binding?");
1885-
BindingListener listener(pattern, initializer, DC);
1888+
BindingListener listener(pattern, initializer, DC, skipClosures);
18861889

18871890
TypeLoc contextualType;
18881891
auto contextualPurpose = CTP_Unused;
@@ -1903,9 +1906,13 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
19031906
}
19041907

19051908
// Type-check the initializer.
1909+
TypeCheckExprOptions flags = TypeCheckExprFlags::ConvertTypeIsOnlyAHint;
1910+
if (skipClosures)
1911+
flags |= TypeCheckExprFlags::SkipMultiStmtClosures;
1912+
19061913
bool hadError = typeCheckExpression(initializer, DC, contextualType,
19071914
contextualPurpose,
1908-
TypeCheckExprFlags::ConvertTypeIsOnlyAHint,
1915+
flags,
19091916
&listener);
19101917

19111918
if (hadError && !pattern->hasType()) {
@@ -1924,7 +1931,8 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
19241931
}
19251932

19261933
bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
1927-
unsigned patternNumber) {
1934+
unsigned patternNumber,
1935+
bool skipClosures) {
19281936

19291937
Pattern *pattern = PBD->getPattern(patternNumber);
19301938
Expr *init = PBD->getInit(patternNumber);
@@ -1944,7 +1952,7 @@ bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
19441952
DC = initContext;
19451953
}
19461954

1947-
bool hadError = typeCheckBinding(pattern, init, DC);
1955+
bool hadError = typeCheckBinding(pattern, init, DC, skipClosures);
19481956
PBD->setPattern(patternNumber, pattern, initContext);
19491957
PBD->setInit(patternNumber, init);
19501958

@@ -2271,7 +2279,7 @@ bool TypeChecker::typeCheckStmtCondition(StmtCondition &cond, DeclContext *dc,
22712279
// If the pattern didn't get a type, it's because we ran into some
22722280
// unknown types along the way. We'll need to check the initializer.
22732281
auto init = elt.getInitializer();
2274-
hadError |= typeCheckBinding(pattern, init, dc);
2282+
hadError |= typeCheckBinding(pattern, init, dc, /*skipClosures*/false);
22752283
elt.setPattern(pattern);
22762284
elt.setInitializer(init);
22772285
hadAnyFalsable |= pattern->isRefutablePattern();
@@ -2505,7 +2513,9 @@ bool TypeChecker::convertToType(Expr *&expr, Type type, DeclContext *dc,
25052513
// Perform the conversion.
25062514
Expr *result = solution.coerceToType(expr, type,
25072515
cs.getConstraintLocator(expr),
2508-
false, typeFromPattern);
2516+
/*ignoreTopLevelInjection*/false,
2517+
/*skipClosures*/false,
2518+
typeFromPattern);
25092519
if (!result) {
25102520
return true;
25112521
}

lib/Sema/TypeCheckDecl.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,9 +1059,14 @@ static void validatePatternBindingDecl(TypeChecker &tc,
10591059

10601060
// If the pattern didn't get a type or if it contains an unbound generic type,
10611061
// we'll need to check the initializer.
1062-
if (!pattern->hasType() || pattern->getType()->hasUnboundGenericType())
1063-
if (tc.typeCheckPatternBinding(binding, entryNumber))
1062+
if (!pattern->hasType() || pattern->getType()->hasUnboundGenericType()) {
1063+
bool skipClosures = false;
1064+
if (auto var = binding->getSingleVar())
1065+
skipClosures = var->getAttrs().hasAttribute<LazyAttr>();
1066+
1067+
if (tc.typeCheckPatternBinding(binding, entryNumber, skipClosures))
10641068
return;
1069+
}
10651070

10661071
// If the pattern binding appears in a type or library file context, then
10671072
// it must bind at least one variable.
@@ -3694,7 +3699,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
36943699
if (!IsFirstPass) {
36953700
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i != e; ++i) {
36963701
if (!PBD->isInitializerChecked(i) && PBD->getInit(i))
3697-
TC.typeCheckPatternBinding(PBD, i);
3702+
TC.typeCheckPatternBinding(PBD, i, /*skipClosures*/false);
36983703
}
36993704
}
37003705

@@ -3725,7 +3730,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
37253730
// If we got a default initializer, install it and re-type-check it
37263731
// to make sure it is properly coerced to the pattern type.
37273732
PBD->setInit(i, defaultInit);
3728-
TC.typeCheckPatternBinding(PBD, i);
3733+
TC.typeCheckPatternBinding(PBD, i, /*skipClosures*/false);
37293734
}
37303735
}
37313736
}
@@ -8046,8 +8051,6 @@ static void validateAttributes(TypeChecker &TC, Decl *D) {
80468051
} else if (auto *func = dyn_cast<FuncDecl>(D)) {
80478052
if (!checkObjCDeclContext(D))
80488053
error = diag::invalid_objc_decl_context;
8049-
else if (func->isOperator())
8050-
error = diag::objc_operator;
80518054
else if (func->isAccessor() && !func->isGetterOrSetter())
80528055
error = diag::objc_observing_accessor;
80538056
} else if (isa<ConstructorDecl>(D) ||

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ void TypeChecker::configureInterfaceType(AbstractFunctionDecl *func,
655655
// Produce an error that this generic parameter cannot be bound.
656656
diagnose(paramDecl->getLoc(), diag::unreferenced_generic_parameter,
657657
paramDecl->getNameStr());
658+
func->setInterfaceType(ErrorType::get(Context));
658659
func->setInvalid();
659660
}
660661
}

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ namespace {
150150
}
151151

152152
// Dig out the witness.
153-
ValueDecl *witness;
153+
ValueDecl *witness = nullptr;
154154
auto concrete = conformance->getConcrete();
155155
if (auto assocType = dyn_cast<AssociatedTypeDecl>(found)) {
156156
// If we're validating the protocol recursively, bail out.
@@ -159,14 +159,7 @@ namespace {
159159

160160
witness = concrete->getTypeWitnessSubstAndDecl(assocType, &TC)
161161
.second;
162-
} else if (isa<TypeAliasDecl>(found)) {
163-
// No witness for typealiases. This means typealiases in
164-
// protocols cannot be found if PerformConformanceCheck
165-
// is on.
166-
//
167-
// FIXME: Fix this.
168-
return;
169-
} else {
162+
} else if (TC.isRequirement(found)) {
170163
witness = concrete->getWitness(found, &TC).getDecl();
171164
}
172165

@@ -298,17 +291,13 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
298291
NameLookupOptions options) {
299292
LookupTypeResult result;
300293

301-
// Look through an inout type.
302-
if (auto inout = type->getAs<InOutType>())
303-
type = inout->getObjectType();
304-
305-
// Look through the metatype.
306-
if (auto metaT = type->getAs<AnyMetatypeType>())
307-
type = metaT->getInstanceType();
308-
309-
// Callers must cope with dependent types directly.
310-
assert(!type->isTypeParameter());
311-
294+
// Structural types do not have member types.
295+
if (!type->is<ArchetypeType>() &&
296+
!type->isExistentialType() &&
297+
!type->getAnyNominal() &&
298+
!type->is<ModuleType>())
299+
return result;
300+
312301
// Look for members with the given name.
313302
SmallVector<ValueDecl *, 4> decls;
314303
NLOptions subOptions = NL_QualifiedDefault | NL_OnlyTypes;

lib/Sema/TypeCheckPattern.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,7 +1295,7 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
12951295
/*suppressDiagnostics=*/ type->hasError());
12961296
switch (castKind) {
12971297
case CheckedCastKind::Unresolved:
1298-
return false;
1298+
return true;
12991299
case CheckedCastKind::Coercion:
13001300
// If this is an 'as' pattern coercing between two different types, then
13011301
// it is "useful" because it is providing a different type to the

0 commit comments

Comments
 (0)