Skip to content

Commit d2c579d

Browse files
committed
Sema: Move some checks from validateType() down to resolveType()
validateType() is just the TypeLoc-based wrapper; it should not do any checks that resolveType() itself does not do.
1 parent de8745b commit d2c579d

File tree

3 files changed

+48
-68
lines changed

3 files changed

+48
-68
lines changed

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -259,44 +259,23 @@ diagnoseGenericArgumentsExportability(SourceLoc loc,
259259
return hadAnyIssues;
260260
}
261261

262-
void TypeChecker::diagnoseGenericTypeExportability(const TypeLoc &TL,
262+
void TypeChecker::diagnoseGenericTypeExportability(SourceLoc Loc, Type T,
263263
const DeclContext *DC) {
264-
class GenericTypeFinder : public TypeDeclFinder {
265-
using Callback = llvm::function_ref<void(SubstitutionMap)>;
266-
267-
const SourceFile &SF;
268-
Callback callback;
269-
public:
270-
GenericTypeFinder(const SourceFile &SF, Callback callback)
271-
: SF(SF), callback(callback) {}
272-
273-
274-
Action visitBoundGenericType(BoundGenericType *ty) override {
275-
ModuleDecl *useModule = SF.getParentModule();
276-
SubstitutionMap subs = ty->getContextSubstitutionMap(useModule,
277-
ty->getDecl());
278-
callback(subs);
279-
return Action::Continue;
280-
}
281-
282-
Action visitTypeAliasType(TypeAliasType *ty) override {
283-
callback(ty->getSubstitutionMap());
284-
return Action::Continue;
285-
}
286-
};
287-
288-
assert(TL.getType() && "type not validated yet");
289-
290264
const SourceFile *SF = DC->getParentSourceFile();
291265
if (!SF)
292266
return;
293267

294-
TL.getType().walk(GenericTypeFinder(*SF, [&](SubstitutionMap subs) {
295-
// FIXME: It would be nice to highlight just the part of the type that's
296-
// problematic, but unfortunately the TypeRepr doesn't have the
297-
// information we need and the Type doesn't easily map back to it.
298-
(void)diagnoseGenericArgumentsExportability(TL.getLoc(), subs, *SF);
299-
}));
268+
// FIXME: It would be nice to highlight just the part of the type that's
269+
// problematic, but unfortunately the TypeRepr doesn't have the
270+
// information we need and the Type doesn't easily map back to it.
271+
if (auto *BGT = dyn_cast<BoundGenericType>(T.getPointer())) {
272+
ModuleDecl *useModule = SF->getParentModule();
273+
auto subs = T->getContextSubstitutionMap(useModule, BGT->getDecl());
274+
(void)diagnoseGenericArgumentsExportability(Loc, subs, *SF);
275+
} else if (auto *TAT = dyn_cast<TypeAliasType>(T.getPointer())) {
276+
auto subs = TAT->getSubstitutionMap();
277+
(void)diagnoseGenericArgumentsExportability(Loc, subs, *SF);
278+
}
300279
}
301280

302281
bool

lib/Sema/TypeCheckType.cpp

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,12 @@ Type TypeChecker::applyGenericArguments(Type type,
730730
if (!result)
731731
return result;
732732

733+
if (!options.contains(TypeResolutionFlags::AllowUnavailable)) {
734+
if (options.isAnyExpr() || dc->getParent()->isLocalContext())
735+
if (dc->getResilienceExpansion() == ResilienceExpansion::Minimal)
736+
diagnoseGenericTypeExportability(loc, result, dc);
737+
}
738+
733739
// Migration hack.
734740
bool isMutablePointer;
735741
if (isPointerToVoid(dc->getASTContext(), result, isMutablePointer)) {
@@ -1657,10 +1663,9 @@ static bool validateAutoClosureAttr(DiagnosticEngine &Diags, const SourceLoc &lo
16571663
/// has `@autoclosure` attribute, and if so, validate that such use is correct.
16581664
/// \returns true if there was an error, false otherwise.
16591665
static bool validateAutoClosureAttributeUse(DiagnosticEngine &Diags,
1660-
const TypeLoc &loc,
1666+
const TypeRepr *TR,
16611667
Type type,
16621668
TypeResolutionOptions options) {
1663-
auto *TR = loc.getTypeRepr();
16641669
if (!TR || TR->isInvalid())
16651670
return false;
16661671

@@ -1683,7 +1688,7 @@ static bool validateAutoClosureAttributeUse(DiagnosticEngine &Diags,
16831688
isValid &= llvm::none_of(
16841689
fnType->getParams(), [&](const FunctionType::Param &param) {
16851690
return param.isAutoClosure() &&
1686-
validateAutoClosureAttr(Diags, loc.getLoc(),
1691+
validateAutoClosureAttr(Diags, TR->getLoc(),
16871692
param.getPlainType());
16881693
});
16891694
}
@@ -1702,30 +1707,8 @@ bool TypeChecker::validateType(ASTContext &Context, TypeLoc &Loc,
17021707
if (Context.Stats)
17031708
Context.Stats->getFrontendCounters().NumTypesValidated++;
17041709

1705-
Type type = Loc.getType();
1706-
if (type.isNull()) {
1707-
type = resolution.resolveType(Loc.getTypeRepr(), options);
1708-
if (!type) {
1709-
type = ErrorType::get(Context);
1710-
// Diagnose types that are illegal in SIL.
1711-
} else if (options.contains(TypeResolutionFlags::SILType)
1712-
&& !type->isLegalSILType()) {
1713-
Context.Diags.diagnose(Loc.getLoc(), diag::illegal_sil_type, type);
1714-
Loc.setInvalidType(Context);
1715-
return true;
1716-
} else if (validateAutoClosureAttributeUse(Context.Diags, Loc,
1717-
type, options)) {
1718-
type = ErrorType::get(Context);
1719-
}
1720-
}
1721-
1710+
Type type = resolution.resolveType(Loc.getTypeRepr(), options);
17221711
Loc.setType(type);
1723-
if (!type->hasError()) {
1724-
const DeclContext *DC = resolution.getDeclContext();
1725-
if (options.isAnyExpr() || DC->getParent()->isLocalContext())
1726-
if (DC->getResilienceExpansion() == ResilienceExpansion::Minimal)
1727-
TypeChecker::diagnoseGenericTypeExportability(Loc, DC);
1728-
}
17291712

17301713
return type->hasError();
17311714
}
@@ -1828,16 +1811,34 @@ namespace {
18281811

18291812
Type TypeResolution::resolveType(TypeRepr *TyR,
18301813
TypeResolutionOptions options) {
1831-
FrontendStatsTracer StatsTracer(getASTContext().Stats, "resolve-type", TyR);
1832-
PrettyStackTraceTypeRepr stackTrace(getASTContext(), "resolving", TyR);
1814+
auto &ctx = getASTContext();
1815+
1816+
FrontendStatsTracer StatsTracer(ctx.Stats, "resolve-type", TyR);
1817+
PrettyStackTraceTypeRepr stackTrace(ctx, "resolving", TyR);
18331818

18341819
TypeResolver typeResolver(*this);
18351820
auto result = typeResolver.resolveType(TyR, options);
1836-
1837-
// If we resolved down to an error, make sure to mark the typeRepr as invalid
1838-
// so we don't produce a redundant diagnostic.
1839-
if (result && result->hasError())
1840-
TyR->setInvalid();
1821+
1822+
if (result) {
1823+
// If we resolved down to an error, make sure to mark the typeRepr as invalid
1824+
// so we don't produce a redundant diagnostic.
1825+
if (result->hasError()) {
1826+
TyR->setInvalid();
1827+
return result;
1828+
}
1829+
1830+
auto loc = TyR->getLoc();
1831+
1832+
if (options.contains(TypeResolutionFlags::SILType)
1833+
&& !result->isLegalSILType()) {
1834+
ctx.Diags.diagnose(loc, diag::illegal_sil_type, result);
1835+
return ErrorType::get(ctx);
1836+
}
1837+
1838+
if (validateAutoClosureAttributeUse(ctx.Diags, TyR, result, options))
1839+
return ErrorType::get(ctx);
1840+
}
1841+
18411842
return result;
18421843
}
18431844

lib/Sema/TypeChecker.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,17 +1760,17 @@ class TypeChecker final : public LazyResolver {
17601760
const DeclContext *DC,
17611761
FragileFunctionKind fragileKind);
17621762

1763+
public:
17631764
/// Given that a type is used from a particular context which
17641765
/// exposes it in the interface of the current module, diagnose if its
17651766
/// generic arguments require the use of conformances that cannot reasonably
17661767
/// be shared.
17671768
///
17681769
/// This method \e only checks how generic arguments are used; it is assumed
17691770
/// that the declarations involved have already been checked elsewhere.
1770-
static void diagnoseGenericTypeExportability(const TypeLoc &TL,
1771+
static void diagnoseGenericTypeExportability(SourceLoc loc, Type type,
17711772
const DeclContext *DC);
17721773

1773-
public:
17741774
/// Given that \p DC is within a fragile context for some reason, describe
17751775
/// why.
17761776
///

0 commit comments

Comments
 (0)