Skip to content

Commit 6ab29cb

Browse files
committed
Introduce NeverNullType to Assert resolveType Never Returns the null Type
1 parent eacc130 commit 6ab29cb

File tree

2 files changed

+60
-31
lines changed

2 files changed

+60
-31
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,6 +1647,34 @@ namespace {
16471647
const auto DefaultParameterConvention = ParameterConvention::Direct_Unowned;
16481648
const auto DefaultResultConvention = ResultConvention::Unowned;
16491649

1650+
/// A wrapper that ensures that the returned type from
1651+
/// \c TypeResolver::resolveType is never the null \c Type. It otherwise
1652+
/// tries to behave like \c Type, so it provides the proper conversion and
1653+
/// arrow operators.
1654+
class NeverNullType final {
1655+
public:
1656+
/// Forbid default construction.
1657+
NeverNullType() = delete;
1658+
/// Forbid construction from \c nullptr.
1659+
NeverNullType(std::nullptr_t) = delete;
1660+
1661+
public:
1662+
/// Construct a never-null Type. If \p Ty is null, a fatal error is thrown.
1663+
NeverNullType(Type Ty) : WrappedTy(Ty) {
1664+
if (Ty.isNull()) {
1665+
llvm::report_fatal_error("Resolved to null type!");
1666+
}
1667+
}
1668+
1669+
operator Type() const { return WrappedTy; }
1670+
Type get() const { return WrappedTy; }
1671+
1672+
TypeBase *operator->() const { return WrappedTy.operator->(); }
1673+
1674+
private:
1675+
Type WrappedTy;
1676+
};
1677+
16501678
class TypeResolver {
16511679
ASTContext &Context;
16521680
TypeResolution resolution;
@@ -1660,7 +1688,7 @@ namespace {
16601688
{
16611689
}
16621690

1663-
Type resolveType(TypeRepr *repr, TypeResolutionOptions options);
1691+
NeverNullType resolveType(TypeRepr *repr, TypeResolutionOptions options);
16641692

16651693
private:
16661694
template<typename ...ArgTypes>
@@ -1795,7 +1823,8 @@ Type ResolveTypeRequest::evaluate(Evaluator &evaluator,
17951823
return result;
17961824
}
17971825

1798-
Type TypeResolver::resolveType(TypeRepr *repr, TypeResolutionOptions options) {
1826+
NeverNullType TypeResolver::resolveType(TypeRepr *repr,
1827+
TypeResolutionOptions options) {
17991828
assert(repr && "Cannot validate null TypeReprs!");
18001829

18011830
// If we know the type representation is invalid, just return an
@@ -1891,9 +1920,9 @@ Type TypeResolver::resolveType(TypeRepr *repr, TypeResolutionOptions options) {
18911920
options |= TypeResolutionFlags::SilenceErrors;
18921921
auto constraintType = resolveType(opaqueRepr->getConstraint(),
18931922
options);
1894-
1895-
return constraintType && !constraintType->hasError()
1896-
? ErrorType::get(constraintType) : ErrorType::get(Context);
1923+
1924+
return !constraintType->hasError() ? ErrorType::get(constraintType)
1925+
: ErrorType::get(Context);
18971926
}
18981927

18991928
case TypeReprKind::Fixed:
@@ -1976,7 +2005,7 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
19762005
instanceOptions -= TypeResolutionFlags::SILType;
19772006

19782007
auto instanceTy = resolveType(base, instanceOptions);
1979-
if (!instanceTy || instanceTy->hasError())
2008+
if (instanceTy->hasError())
19802009
return instanceTy;
19812010

19822011
// Check for @thin.
@@ -2440,8 +2469,8 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
24402469
variadic = true;
24412470
}
24422471

2443-
Type ty = resolveType(eltTypeRepr, thisElementOptions);
2444-
if (!ty || ty->hasError()) {
2472+
auto ty = resolveType(eltTypeRepr, thisElementOptions);
2473+
if (ty->hasError()) {
24452474
elements.emplace_back(ErrorType::get(Context));
24462475
continue;
24472476
}
@@ -2550,7 +2579,7 @@ Type TypeResolver::resolveOpaqueReturnType(TypeRepr *repr,
25502579
for (auto argRepr : generic->getGenericArgs()) {
25512580
auto argTy = resolveType(argRepr, options);
25522581
// If we cannot resolve the generic parameter, propagate the error out.
2553-
if (!argTy || argTy->hasError()) {
2582+
if (argTy->hasError()) {
25542583
return ErrorType::get(Context);
25552584
}
25562585
TypeArgsBuf.push_back(argTy);
@@ -2594,8 +2623,8 @@ Type TypeResolver::resolveASTFunctionType(
25942623

25952624
auto resultOptions = options.withoutContext();
25962625
resultOptions.setContext(TypeResolverContext::FunctionResult);
2597-
Type outputTy = resolveType(repr->getResultTypeRepr(), resultOptions);
2598-
if (!outputTy || outputTy->hasError()) {
2626+
auto outputTy = resolveType(repr->getResultTypeRepr(), resultOptions);
2627+
if (outputTy->hasError()) {
25992628
return ErrorType::get(Context);
26002629
}
26012630

@@ -3255,8 +3284,8 @@ Type TypeResolver::resolveSpecifierTypeRepr(SpecifierTypeRepr *repr,
32553284

32563285
Type TypeResolver::resolveArrayType(ArrayTypeRepr *repr,
32573286
TypeResolutionOptions options) {
3258-
Type baseTy = resolveType(repr->getBase(), options.withoutContext());
3259-
if (!baseTy || baseTy->hasError()) {
3287+
auto baseTy = resolveType(repr->getBase(), options.withoutContext());
3288+
if (baseTy->hasError()) {
32603289
return ErrorType::get(Context);
32613290
}
32623291

@@ -3272,13 +3301,13 @@ Type TypeResolver::resolveDictionaryType(DictionaryTypeRepr *repr,
32723301
TypeResolutionOptions options) {
32733302
options = adjustOptionsForGenericArgs(options);
32743303

3275-
Type keyTy = resolveType(repr->getKey(), options.withoutContext());
3276-
if (!keyTy || keyTy->hasError()) {
3304+
auto keyTy = resolveType(repr->getKey(), options.withoutContext());
3305+
if (keyTy->hasError()) {
32773306
return ErrorType::get(Context);
32783307
}
32793308

3280-
Type valueTy = resolveType(repr->getValue(), options.withoutContext());
3281-
if (!valueTy || valueTy->hasError()) {
3309+
auto valueTy = resolveType(repr->getValue(), options.withoutContext());
3310+
if (valueTy->hasError()) {
32823311
return ErrorType::get(Context);
32833312
}
32843313

@@ -3304,8 +3333,8 @@ Type TypeResolver::resolveOptionalType(OptionalTypeRepr *repr,
33043333
TypeResolutionOptions elementOptions = options.withoutContext(true);
33053334
elementOptions.setContext(TypeResolverContext::ImmediateOptionalTypeArgument);
33063335

3307-
Type baseTy = resolveType(repr->getBase(), elementOptions);
3308-
if (!baseTy || baseTy->hasError()) {
3336+
auto baseTy = resolveType(repr->getBase(), elementOptions);
3337+
if (baseTy->hasError()) {
33093338
return ErrorType::get(Context);
33103339
}
33113340

@@ -3376,12 +3405,12 @@ Type TypeResolver::resolveImplicitlyUnwrappedOptionalType(
33763405
TypeResolutionOptions elementOptions = options.withoutContext(true);
33773406
elementOptions.setContext(TypeResolverContext::ImmediateOptionalTypeArgument);
33783407

3379-
Type baseTy = resolveType(repr->getBase(), elementOptions);
3380-
if (!baseTy || baseTy->hasError()) {
3408+
auto baseTy = resolveType(repr->getBase(), elementOptions);
3409+
if (baseTy->hasError()) {
33813410
return ErrorType::get(Context);
33823411
}
33833412

3384-
Type uncheckedOptionalTy =
3413+
auto uncheckedOptionalTy =
33853414
TypeChecker::getOptionalType(repr->getExclamationLoc(), baseTy);
33863415
if (uncheckedOptionalTy->hasError()) {
33873416
return ErrorType::get(Context);
@@ -3416,8 +3445,8 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
34163445
for (unsigned i = 0, end = repr->getNumElements(); i != end; ++i) {
34173446
auto *tyR = repr->getElementType(i);
34183447

3419-
Type ty = resolveType(tyR, elementOptions);
3420-
if (!ty || ty->hasError())
3448+
auto ty = resolveType(tyR, elementOptions);
3449+
if (ty->hasError())
34213450
hadError = true;
34223451

34233452
auto eltName = repr->getElementName(i);
@@ -3485,8 +3514,8 @@ Type TypeResolver::resolveCompositionType(CompositionTypeRepr *repr,
34853514
};
34863515

34873516
for (auto tyR : repr->getTypes()) {
3488-
Type ty = resolveType(tyR, options.withoutContext());
3489-
if (!ty || ty->hasError()) return ty;
3517+
auto ty = resolveType(tyR, options.withoutContext());
3518+
if (ty->hasError()) return ty;
34903519

34913520
auto nominalDecl = ty->getAnyNominal();
34923521
if (nominalDecl && isa<ClassDecl>(nominalDecl)) {
@@ -3529,8 +3558,8 @@ Type TypeResolver::resolveCompositionType(CompositionTypeRepr *repr,
35293558
Type TypeResolver::resolveMetatypeType(MetatypeTypeRepr *repr,
35303559
TypeResolutionOptions options) {
35313560
// The instance type of a metatype is always abstract, not SIL-lowered.
3532-
Type ty = resolveType(repr->getBase(), options.withoutContext());
3533-
if (!ty || ty->hasError()) {
3561+
auto ty = resolveType(repr->getBase(), options.withoutContext());
3562+
if (ty->hasError()) {
35343563
return ErrorType::get(Context);
35353564
}
35363565

@@ -3562,8 +3591,8 @@ Type TypeResolver::buildMetatypeType(
35623591
Type TypeResolver::resolveProtocolType(ProtocolTypeRepr *repr,
35633592
TypeResolutionOptions options) {
35643593
// The instance type of a metatype is always abstract, not SIL-lowered.
3565-
Type ty = resolveType(repr->getBase(), options.withoutContext());
3566-
if (!ty || ty->hasError()) {
3594+
auto ty = resolveType(repr->getBase(), options.withoutContext());
3595+
if (ty->hasError()) {
35673596
return ErrorType::get(Context);
35683597
}
35693598

validation-test/compiler_crashers_2_fixed/0163-sr8033.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ protocol P1 {
77
}
88
extension Foo: P1 where A : P1 {} // expected-error {{unsupported recursion for reference to associated type 'A' of type 'Foo<T>'}}
99
// expected-error@-1 {{type 'Foo<T>' does not conform to protocol 'P1'}}
10-
// expected-error@-2 {{type 'Foo<T>' in conformance requirement does not refer to a generic parameter or associated type}}
10+
// expected-error@-2 {{type '<<error type>>' in conformance requirement does not refer to a generic parameter or associated type}}

0 commit comments

Comments
 (0)