Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 33 additions & 21 deletions include/swift/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -595,17 +595,6 @@ template <> struct CanTypeWrapperTraits<TYPE> { \
BEGIN_CAN_TYPE_WRAPPER(TYPE, BASE) \
END_CAN_TYPE_WRAPPER(TYPE, BASE)

// Disallow direct uses of isa/cast/dyn_cast on Type to eliminate a
// certain class of bugs.
template <class X> inline bool
isa(const Type&) = delete; // Use TypeBase::is instead.
template <class X> inline typename llvm::cast_retty<X, Type>::ret_type
cast(const Type&) = delete; // Use TypeBase::castTo instead.
template <class X> inline typename llvm::cast_retty<X, Type>::ret_type
dyn_cast(const Type&) = delete; // Use TypeBase::getAs instead.
template <class X> inline typename llvm::cast_retty<X, Type>::ret_type
dyn_cast_or_null(const Type&) = delete;

// Permit direct uses of isa/cast/dyn_cast on CanType and preserve
// canonicality.
template <class X> inline bool isa(CanType type) {
Expand Down Expand Up @@ -656,16 +645,6 @@ namespace llvm {
return OS;
}

// A Type casts like a TypeBase*.
template<> struct simplify_type<const ::swift::Type> {
typedef ::swift::TypeBase *SimpleType;
static SimpleType getSimplifiedValue(const ::swift::Type &Val) {
return Val.getPointer();
}
};
template<> struct simplify_type< ::swift::Type>
: public simplify_type<const ::swift::Type> {};

// Type hashes just like pointers.
template<> struct DenseMapInfo<swift::Type> {
static swift::Type getEmptyKey() {
Expand Down Expand Up @@ -716,4 +695,37 @@ namespace llvm {
};
} // end namespace llvm

/// Disallow uses of `isa`/`cast`/`dyn_cast` directly on `Type` to eliminate a
/// certain class of bugs.
namespace llvm {

template <class To>
struct CastInfo<To, const swift::Type> {
// FIXME: Without this 'false' indirection, clang from 5.9 toolchain
// triggers the static assert directly on the template. Try removing once
// Linux CI is updated to 6.0.
static constexpr bool False() { return false; }
static_assert(
False(), "don't use isa/cast/dyn_cast directly on a 'Type' value; "
"instead, use 'isa/cast/dyn_cast<X>(type.getPointer())' to "
"cast the exact type, or use 'type->is/getAs/castTo<X>()' "
"to cast the desugared type, which is usually the right choice");
};
template <class To>
struct CastInfo<To, swift::Type> : public CastInfo<To, const swift::Type> {};

/// These specializations exist to avoid unhelpful instantiation errors in
/// addition to the above static assertion.
template <>
struct simplify_type<const swift::Type> {
typedef ::swift::TypeBase *SimpleType;
static SimpleType getSimplifiedValue(const swift::Type &Val) {
return Val.getPointer();
}
};
template <>
struct simplify_type<swift::Type> : public simplify_type<const swift::Type> {};

} // namespace llvm

#endif
4 changes: 2 additions & 2 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4397,8 +4397,8 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {

if (decl->hasSendingResult()) {
Printer << "sending ";
} else if (auto *ft = llvm::dyn_cast_if_present<AnyFunctionType>(
decl->getInterfaceType())) {
} else if (auto *ft =
decl->getInterfaceType()->getAs<AnyFunctionType>()) {
if (ft->hasExtInfo() && ft->hasSendingResult()) {
Printer << "sending ";
}
Expand Down
4 changes: 2 additions & 2 deletions lib/AST/TypeSubstitution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,7 @@ ProtocolConformanceRef swift::substOpaqueTypesWithUnderlyingTypes(
ProtocolConformanceRef ReplaceOpaqueTypesWithUnderlyingTypes::
operator()(InFlightSubstitution &IFS, Type maybeOpaqueType,
ProtocolDecl *protocol) const {
auto archetype = dyn_cast<OpaqueTypeArchetypeType>(maybeOpaqueType);
auto *archetype = maybeOpaqueType->getAs<OpaqueTypeArchetypeType>();
if (!archetype)
return ProtocolConformanceRef::forAbstract(maybeOpaqueType, protocol);

Expand Down Expand Up @@ -1194,7 +1194,7 @@ Type ReplaceExistentialArchetypesWithConcreteTypes::operator()(

ProtocolConformanceRef ReplaceExistentialArchetypesWithConcreteTypes::operator()(
InFlightSubstitution &IFS, Type origType, ProtocolDecl *proto) const {
auto existentialArchetype = dyn_cast<ExistentialArchetypeType>(origType);
auto *existentialArchetype = origType->getAs<ExistentialArchetypeType>();
if (!existentialArchetype ||
existentialArchetype->getGenericEnvironment() != env)
return ProtocolConformanceRef::forAbstract(origType.subst(IFS), proto);
Expand Down
2 changes: 1 addition & 1 deletion lib/ConstExtract/ConstExtract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1392,7 +1392,7 @@ void writeAssociatedTypeAliases(llvm::json::OStream &JSON,
toFullyQualifiedTypeNameString(type));
JSON.attribute("substitutedMangledTypeName",
toMangledTypeNameString(type));
if (auto OpaqueTy = dyn_cast<OpaqueTypeArchetypeType>(type)) {
if (auto *OpaqueTy = type->getAs<OpaqueTypeArchetypeType>()) {
writeSubstitutedOpaqueTypeAliasDetails(JSON, *OpaqueTy);
}
});
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3601,7 +3601,7 @@ bool swift::irgen::hasValidSignatureForEmbedded(SILFunction *f) {
auto s = f->getLoweredFunctionType()->getInvocationGenericSignature();
for (auto genParam : s.getGenericParams()) {
auto mappedParam = f->getGenericEnvironment()->mapTypeIntoEnvironment(genParam);
if (auto archeTy = dyn_cast<ArchetypeType>(mappedParam)) {
if (auto *archeTy = mappedParam->getAs<ArchetypeType>()) {
if (archeTy->requiresClass())
continue;
}
Expand Down
7 changes: 4 additions & 3 deletions lib/IRGen/IRGenDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1599,7 +1599,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
std::vector<Type> GenericArgs;
Type CurrentType = BGT;
while (CurrentType && CurrentType->getAnyNominal()) {
if (auto *BGT = llvm::dyn_cast<BoundGenericType>(CurrentType))
if (auto *BGT = CurrentType->getAs<BoundGenericType>())
GenericArgs.insert(GenericArgs.end(), BGT->getGenericArgs().begin(),
BGT->getGenericArgs().end());
CurrentType = CurrentType->getNominalParent();
Expand Down Expand Up @@ -2460,9 +2460,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
return TypeWalker::Action::Stop;

DeclContext *D = nullptr;
if (auto *TAT = llvm::dyn_cast<TypeAliasType>(T))
if (auto *TAT = llvm::dyn_cast<TypeAliasType>(T.getPointer()))
D = TAT->getDecl()->getDeclContext();
else if (auto *NT = llvm::dyn_cast<NominalOrBoundGenericNominalType>(T))
else if (auto *NT = llvm::dyn_cast<NominalOrBoundGenericNominalType>(
T.getPointer()))
D = NT->getDecl()->getDeclContext();

// A type inside a function uses that function's signature as part of
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9977,7 +9977,7 @@ ConstraintSystem::matchPackElementType(Type elementType, Type patternType,
return tryFix([&]() {
auto envShape = genericEnv->mapTypeIntoEnvironment(
genericEnv->getOpenedElementShapeClass());
if (auto *pack = dyn_cast<PackType>(envShape))
if (auto *pack = dyn_cast<PackType>(envShape.getPointer()))
envShape = pack->unwrapSingletonPackExpansion()->getPatternType();

return SkipSameShapeRequirement::create(
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/IDETypeCheckingRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ static bool isExtensionAppliedInternal(const DeclContext *DC, Type BaseTy,
return true;

ProtocolDecl *BaseTypeProtocolDecl = nullptr;
if (auto opaqueType = dyn_cast<OpaqueTypeArchetypeType>(BaseTy)) {
if (auto *opaqueType = BaseTy->getAs<OpaqueTypeArchetypeType>()) {
if (opaqueType->getConformsTo().size() == 1) {
BaseTypeProtocolDecl = opaqueType->getConformsTo().front();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckAvailability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2627,7 +2627,7 @@ class ExprAvailabilityWalker : public BaseDiagnosticWalker {
if (ty->isKnownImmutableKeyPathType())
return StorageAccessKind::Get;

if (auto existential = dyn_cast<ExistentialType>(ty)) {
if (auto *existential = ty->getAs<ExistentialType>()) {
if (auto superclass =
existential->getExistentialLayout().getSuperclass()) {
if (superclass->isKnownImmutableKeyPathType())
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5412,7 +5412,7 @@ TypeResolver::resolveIsolatedTypeRepr(IsolatedTypeRepr *repr,
unwrappedType = wrappedOptionalType;
}

if (auto dynamicSelfType = dyn_cast<DynamicSelfType>(unwrappedType)) {
if (auto *dynamicSelfType = unwrappedType->getAs<DynamicSelfType>()) {
unwrappedType = dynamicSelfType->getSelfType();
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Serialization/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5626,7 +5626,7 @@ struct ImplementationOnlyWalker : TypeWalker {
const ModuleDecl *currentModule;
ImplementationOnlyWalker(const ModuleDecl *M) : currentModule(M) {}
Action walkToTypePre(Type ty) override {
if (auto *typeAlias = dyn_cast<TypeAliasType>(ty)) {
if (auto *typeAlias = dyn_cast<TypeAliasType>(ty.getPointer())) {
if (importedImplementationOnly(typeAlias->getDecl()))
return Action::Stop;
} else if (auto *nominal = ty->getAs<NominalType>()) {
Expand Down