Remove the notion of 'unresolved' types entirely.

Unresolved types are a holdover from the old type checker that not
longer have any purpose in the type system.


Swift SVN r6242
This commit is contained in:
Doug Gregor
2013-07-13 05:27:22 +00:00
parent d42e385371
commit cf9b8a302e
9 changed files with 33 additions and 93 deletions

View File

@@ -78,9 +78,6 @@ class alignas(8) TypeBase {
const TypeKind Kind; const TypeKind Kind;
struct TypeBaseBits { struct TypeBaseBits {
/// Unresolved - Whether this type is unresolved.
unsigned Unresolved : 1;
/// \brief Whether this type has a type variable somewhere in it. /// \brief Whether this type has a type variable somewhere in it.
unsigned HasTypeVariable : 1; unsigned HasTypeVariable : 1;
@@ -91,28 +88,23 @@ class alignas(8) TypeBase {
/// 2 -> valid /// 2 -> valid
unsigned Validated : 2; unsigned Validated : 2;
}; };
static const unsigned NumTypeBaseBits = 4; static const unsigned NumTypeBaseBits = 3;
union { union {
TypeBaseBits TypeBase; TypeBaseBits TypeBase;
} TypeBits; } TypeBits;
protected: protected:
TypeBase(TypeKind kind, ASTContext *CanTypeCtx, bool Unresolved, TypeBase(TypeKind kind, ASTContext *CanTypeCtx, bool HasTypeVariable)
bool HasTypeVariable)
: CanonicalType((TypeBase*)nullptr), Kind(kind) { : CanonicalType((TypeBase*)nullptr), Kind(kind) {
// If this type is canonical, switch the CanonicalType union to ASTContext. // If this type is canonical, switch the CanonicalType union to ASTContext.
if (CanTypeCtx) if (CanTypeCtx)
CanonicalType = CanTypeCtx; CanonicalType = CanTypeCtx;
setUnresolved(Unresolved);
setHasTypeVariable(HasTypeVariable); setHasTypeVariable(HasTypeVariable);
TypeBits.TypeBase.Validated = 0; TypeBits.TypeBase.Validated = 0;
} }
/// \brief Mark this type as unresolved.
void setUnresolved(bool D = true) { TypeBits.TypeBase.Unresolved = D; }
/// \brief Mark this type as having a type variable. /// \brief Mark this type as having a type variable.
void setHasTypeVariable(bool TV = true) { void setHasTypeVariable(bool TV = true) {
TypeBits.TypeBase.HasTypeVariable = TV; TypeBits.TypeBase.HasTypeVariable = TV;
@@ -187,12 +179,7 @@ public:
/// allowsOwnership() - Are variables of this type permitted to have /// allowsOwnership() - Are variables of this type permitted to have
/// ownership attributes? /// ownership attributes?
bool allowsOwnership(); bool allowsOwnership();
/// isUnresolvedType() - Determines whether this type is an unresolved
/// type, meaning that part of the type depends on the context in which
/// the type occurs.
bool isUnresolvedType() const;
/// \brief Determine whether this type involves a type variable. /// \brief Determine whether this type involves a type variable.
bool hasTypeVariable() const; bool hasTypeVariable() const;
@@ -311,8 +298,7 @@ class ErrorType : public TypeBase {
friend class ASTContext; friend class ASTContext;
// The Error type is always canonical. // The Error type is always canonical.
ErrorType(ASTContext &C) ErrorType(ASTContext &C)
: TypeBase(TypeKind::Error, &C, /*Unresolved=*/false, : TypeBase(TypeKind::Error, &C, /*HasTypeVariable=*/false) { }
/*HasTypeVariable=*/false) { }
public: public:
static Type get(ASTContext &C); static Type get(ASTContext &C);
@@ -328,8 +314,7 @@ public:
class BuiltinType : public TypeBase { class BuiltinType : public TypeBase {
protected: protected:
BuiltinType(TypeKind kind, ASTContext &canTypeCtx) BuiltinType(TypeKind kind, ASTContext &canTypeCtx)
: TypeBase(kind, &canTypeCtx, /*unresolved*/ false, : TypeBase(kind, &canTypeCtx, /*HasTypeVariable=*/false) {}
/*HasTypeVariable=*/false) {}
public: public:
static bool classof(const TypeBase *T) { static bool classof(const TypeBase *T) {
return T->getKind() >= TypeKind::First_BuiltinType && return T->getKind() >= TypeKind::First_BuiltinType &&
@@ -503,8 +488,7 @@ class NameAliasType : public TypeBase {
friend class TypeAliasDecl; friend class TypeAliasDecl;
// NameAliasType are never canonical. // NameAliasType are never canonical.
NameAliasType(TypeAliasDecl *d) NameAliasType(TypeAliasDecl *d)
: TypeBase(TypeKind::NameAlias, nullptr, /*Unresolved=*/false, : TypeBase(TypeKind::NameAlias, nullptr, /*HasTypeVariable=*/false),
/*HasTypeVariable=*/false),
TheDecl(d) {} TheDecl(d) {}
TypeAliasDecl *const TheDecl; TypeAliasDecl *const TheDecl;
@@ -558,8 +542,7 @@ public:
private: private:
// IdentifierType are never canonical. // IdentifierType are never canonical.
IdentifierType(MutableArrayRef<Component> Components) IdentifierType(MutableArrayRef<Component> Components)
: TypeBase(TypeKind::Identifier, nullptr, /*Unresolved=*/false, : TypeBase(TypeKind::Identifier, nullptr, /*HasTypeVariable=*/false),
/*HasTypeVariable=*/false),
Components(Components) {} Components(Components) {}
public: public:
@@ -604,8 +587,7 @@ class ParenType : public TypeBase {
friend class ASTContext; friend class ASTContext;
ParenType(Type UnderlyingType, bool HasTypeVariable) ParenType(Type UnderlyingType, bool HasTypeVariable)
: TypeBase(TypeKind::Paren, nullptr, UnderlyingType->isUnresolvedType(), : TypeBase(TypeKind::Paren, nullptr, HasTypeVariable),
HasTypeVariable),
UnderlyingType(UnderlyingType) {} UnderlyingType(UnderlyingType) {}
public: public:
Type getUnderlyingType() const { return UnderlyingType; } Type getUnderlyingType() const { return UnderlyingType; }
@@ -739,7 +721,7 @@ private:
bool hasTypeVariable) bool hasTypeVariable)
: TypeBase(TypeKind::UnboundGeneric, : TypeBase(TypeKind::UnboundGeneric,
(!Parent || Parent->isCanonical())? &C : nullptr, (!Parent || Parent->isCanonical())? &C : nullptr,
/*Unresolved=*/false, hasTypeVariable), hasTypeVariable),
TheDecl(TheDecl), Parent(Parent) { } TheDecl(TheDecl), Parent(Parent) { }
public: public:
@@ -944,7 +926,7 @@ protected:
NominalType(TypeKind K, ASTContext *C, NominalTypeDecl *TheDecl, NominalType(TypeKind K, ASTContext *C, NominalTypeDecl *TheDecl,
Type Parent, bool HasTypeVariable) Type Parent, bool HasTypeVariable)
: TypeBase(K, (!Parent || Parent->isCanonical())? C : nullptr, : TypeBase(K, (!Parent || Parent->isCanonical())? C : nullptr,
/*Unresolved=*/false, HasTypeVariable), HasTypeVariable),
TheDecl(TheDecl), Parent(Parent) { } TheDecl(TheDecl), Parent(Parent) { }
public: public:
@@ -1106,7 +1088,7 @@ public:
private: private:
ModuleType(Module *M, ASTContext &Ctx) ModuleType(Module *M, ASTContext &Ctx)
: TypeBase(TypeKind::Module, &Ctx, // Always canonical : TypeBase(TypeKind::Module, &Ctx, // Always canonical
/*Unresolved=*/false, /*HasTypeVariable=*/false), /*HasTypeVariable=*/false),
TheModule(M) { TheModule(M) {
} }
}; };
@@ -1144,9 +1126,9 @@ class AnyFunctionType : public TypeBase {
const llvm::PointerIntPair<Type, 1, bool> OutputAndIsThin; const llvm::PointerIntPair<Type, 1, bool> OutputAndIsThin;
protected: protected:
AnyFunctionType(TypeKind Kind, ASTContext *CanTypeContext, AnyFunctionType(TypeKind Kind, ASTContext *CanTypeContext,
Type Input, Type Output, bool isUnresolved, Type Input, Type Output, bool HasTypeVariable,
bool HasTypeVariable, bool isThin, AbstractCC cc) bool isThin, AbstractCC cc)
: TypeBase(Kind, CanTypeContext, isUnresolved, HasTypeVariable), : TypeBase(Kind, CanTypeContext, HasTypeVariable),
InputAndCC(Input, cc), OutputAndIsThin(Output, isThin) { InputAndCC(Input, cc), OutputAndIsThin(Output, isThin) {
} }
@@ -1311,8 +1293,7 @@ private:
class ArraySliceType : public TypeBase { class ArraySliceType : public TypeBase {
// ArraySliceTypes are never canonical. // ArraySliceTypes are never canonical.
ArraySliceType(Type base, bool hasTypeVariable) ArraySliceType(Type base, bool hasTypeVariable)
: TypeBase(TypeKind::ArraySlice, nullptr, : TypeBase(TypeKind::ArraySlice, nullptr, hasTypeVariable),
/*Unresolved=*/base->isUnresolvedType(), hasTypeVariable),
Base(base) {} Base(base) {}
Type Base; Type Base;
@@ -1418,7 +1399,7 @@ private:
ProtocolCompositionType(ASTContext *Ctx, ArrayRef<Type> Protocols) ProtocolCompositionType(ASTContext *Ctx, ArrayRef<Type> Protocols)
: TypeBase(TypeKind::ProtocolComposition, /*Context=*/Ctx, : TypeBase(TypeKind::ProtocolComposition, /*Context=*/Ctx,
/*Unresolved=*/false, /*HasTypeVariable=*/false), /*HasTypeVariable=*/false),
Protocols(Protocols) { } Protocols(Protocols) { }
}; };
@@ -1563,8 +1544,7 @@ private:
LValueType(Type objectTy, Qual quals, ASTContext *canonicalContext, LValueType(Type objectTy, Qual quals, ASTContext *canonicalContext,
bool hasTypeVariable) bool hasTypeVariable)
: TypeBase(TypeKind::LValue, canonicalContext, : TypeBase(TypeKind::LValue, canonicalContext, hasTypeVariable),
objectTy->isUnresolvedType(), hasTypeVariable),
ObjectTy(objectTy), Quals(quals) {} ObjectTy(objectTy), Quals(quals) {}
public: public:
@@ -1599,10 +1579,10 @@ class SubstitutableType : public TypeBase {
Type Superclass; Type Superclass;
protected: protected:
SubstitutableType(TypeKind K, ASTContext *C, bool Unresolved, SubstitutableType(TypeKind K, ASTContext *C,
ArrayRef<ProtocolDecl *> ConformsTo, ArrayRef<ProtocolDecl *> ConformsTo,
Type Superclass) Type Superclass)
: TypeBase(K, C, Unresolved, /*HasTypeVariable=*/false), : TypeBase(K, C, /*HasTypeVariable=*/false),
ConformsTo(ConformsTo), Superclass(Superclass) { } ConformsTo(ConformsTo), Superclass(Superclass) { }
public: public:
@@ -1714,8 +1694,7 @@ private:
ArchetypeType(ASTContext &Ctx, ArchetypeType *Parent, ArchetypeType(ASTContext &Ctx, ArchetypeType *Parent,
Identifier Name, ArrayRef<ProtocolDecl *> ConformsTo, Identifier Name, ArrayRef<ProtocolDecl *> ConformsTo,
Type Superclass, Optional<unsigned> Index) Type Superclass, Optional<unsigned> Index)
: SubstitutableType(TypeKind::Archetype, &Ctx, /*Unresolved=*/false, : SubstitutableType(TypeKind::Archetype, &Ctx, ConformsTo, Superclass),
ConformsTo, Superclass),
Parent(Parent), Name(Name), IndexIfPrimary(Index? *Index + 1 : 0) { } Parent(Parent), Name(Name), IndexIfPrimary(Index? *Index + 1 : 0) { }
}; };
@@ -1726,8 +1705,7 @@ class SubstitutedType : public TypeBase {
// SubstitutedTypes are never canonical. // SubstitutedTypes are never canonical.
explicit SubstitutedType(Type Original, Type Replacement, explicit SubstitutedType(Type Original, Type Replacement,
bool HasTypeVariable) bool HasTypeVariable)
: TypeBase(TypeKind::Substituted, nullptr, Replacement->isUnresolvedType(), : TypeBase(TypeKind::Substituted, nullptr, HasTypeVariable),
HasTypeVariable),
Original(Original), Replacement(Replacement) {} Original(Original), Replacement(Replacement) {}
Type Original; Type Original;
@@ -1763,7 +1741,7 @@ public:
/// extremely useful in SIL and IR-generation. /// extremely useful in SIL and IR-generation.
class ReferenceStorageType : public TypeBase { class ReferenceStorageType : public TypeBase {
ReferenceStorageType(Type referent, Ownership ownership, ASTContext *C) ReferenceStorageType(Type referent, Ownership ownership, ASTContext *C)
: TypeBase(TypeKind::ReferenceStorage, C, false, false), : TypeBase(TypeKind::ReferenceStorage, C, false),
Referent(referent), Oship(ownership) {} Referent(referent), Oship(ownership) {}
Type Referent; Type Referent;
@@ -1786,7 +1764,7 @@ public:
/// \brief A type variable used during type checking. /// \brief A type variable used during type checking.
class TypeVariableType : public TypeBase { class TypeVariableType : public TypeBase {
TypeVariableType(ASTContext &C) TypeVariableType(ASTContext &C)
: TypeBase(TypeKind::TypeVariable, &C, true, true) { } : TypeBase(TypeKind::TypeVariable, &C, true) { }
class Implementation; class Implementation;
@@ -1827,10 +1805,6 @@ public:
} }
}; };
inline bool TypeBase::isUnresolvedType() const {
return TypeBits.TypeBase.Unresolved;
}
inline bool TypeBase::hasTypeVariable() const { inline bool TypeBase::hasTypeVariable() const {
return TypeBits.TypeBase.HasTypeVariable; return TypeBits.TypeBase.HasTypeVariable;
} }

View File

@@ -481,19 +481,9 @@ BoundGenericType::BoundGenericType(TypeKind theKind,
ArrayRef<Type> genericArgs, ArrayRef<Type> genericArgs,
ASTContext *context, ASTContext *context,
bool hasTypeVariable) bool hasTypeVariable)
: TypeBase(theKind, context, /*Unresolved=*/false, : TypeBase(theKind, context, hasTypeVariable),
hasTypeVariable),
TheDecl(theDecl), Parent(parent), GenericArgs(genericArgs) TheDecl(theDecl), Parent(parent), GenericArgs(genericArgs)
{ {
// Determine whether this type is unresolved.
if (parent && parent->isUnresolvedType())
setUnresolved();
else for (Type arg : genericArgs) {
if (arg->isUnresolvedType()) {
setUnresolved();
break;
}
}
} }
BoundGenericType *BoundGenericType::get(NominalTypeDecl *TheDecl, BoundGenericType *BoundGenericType::get(NominalTypeDecl *TheDecl,
@@ -695,7 +685,7 @@ MetaTypeType *MetaTypeType::get(Type T, ASTContext &C) {
} }
MetaTypeType::MetaTypeType(Type T, ASTContext *C, bool HasTypeVariable) MetaTypeType::MetaTypeType(Type T, ASTContext *C, bool HasTypeVariable)
: TypeBase(TypeKind::MetaType, C, T->isUnresolvedType(), HasTypeVariable), : TypeBase(TypeKind::MetaType, C, HasTypeVariable),
InstanceType(T) { InstanceType(T) {
} }
@@ -745,7 +735,6 @@ FunctionType::FunctionType(Type input, Type output,
(input->isCanonical() && output->isCanonical()) ? (input->isCanonical() && output->isCanonical()) ?
&input->getASTContext() : 0, &input->getASTContext() : 0,
input, output, input, output,
(input->isUnresolvedType() || output->isUnresolvedType()),
hasTypeVariable, hasTypeVariable,
isThin, isThin,
cc), cc),
@@ -777,7 +766,6 @@ PolymorphicFunctionType::PolymorphicFunctionType(Type input, Type output,
: AnyFunctionType(TypeKind::PolymorphicFunction, : AnyFunctionType(TypeKind::PolymorphicFunction,
(input->isCanonical() && output->isCanonical()) ?&C : 0, (input->isCanonical() && output->isCanonical()) ?&C : 0,
input, output, input, output,
(input->isUnresolvedType() || output->isUnresolvedType()),
/*HasTypeVariable=*/false, /*HasTypeVariable=*/false,
isThin, cc), isThin, cc),
Params(params) Params(params)
@@ -803,7 +791,7 @@ ArrayType *ArrayType::get(Type BaseType, uint64_t Size, ASTContext &C) {
ArrayType::ArrayType(Type base, uint64_t size, bool hasTypeVariable) ArrayType::ArrayType(Type base, uint64_t size, bool hasTypeVariable)
: TypeBase(TypeKind::Array, : TypeBase(TypeKind::Array,
base->isCanonical() ? &base->getASTContext() : 0, base->isCanonical() ? &base->getASTContext() : 0,
base->isUnresolvedType(), hasTypeVariable), hasTypeVariable),
Base(base), Size(size) {} Base(base), Size(size) {}

View File

@@ -721,7 +721,7 @@ public:
void visitIntegerLiteralExpr(IntegerLiteralExpr *E) { void visitIntegerLiteralExpr(IntegerLiteralExpr *E) {
printCommon(E, "integer_literal_expr") << " value="; printCommon(E, "integer_literal_expr") << " value=";
if (E->getType().isNull() || E->getType()->isUnresolvedType()) if (E->getType().isNull())
OS << E->getText(); OS << E->getText();
else else
OS << E->getValue(); OS << E->getValue();

View File

@@ -71,7 +71,7 @@ inline TwoChars checkSourceRangeType(SourceRange (Pattern::*)() const);
void Pattern::setType(Type ty) { void Pattern::setType(Type ty) {
assert(!hasType() || getType()->isUnresolvedType() || assert(!hasType() ||
ty->is<ErrorType>() || ty->is<ErrorType>() ||
ty->getWithoutDefaultArgs(ty->getASTContext())->isEqual( ty->getWithoutDefaultArgs(ty->getASTContext())->isEqual(
Ty->getWithoutDefaultArgs(Ty->getASTContext()))); Ty->getWithoutDefaultArgs(Ty->getASTContext())));

View File

@@ -1097,16 +1097,7 @@ bool TypeBase::isSpelledLike(Type other) {
TupleType::TupleType(ArrayRef<TupleTypeElt> fields, ASTContext *CanCtx, TupleType::TupleType(ArrayRef<TupleTypeElt> fields, ASTContext *CanCtx,
bool hasTypeVariable) bool hasTypeVariable)
: TypeBase(TypeKind::Tuple, CanCtx, /*Unresolved=*/false, hasTypeVariable), : TypeBase(TypeKind::Tuple, CanCtx, hasTypeVariable), Fields(fields) { }
Fields(fields) {
// Determine whether this tuple type is unresolved.
for (const auto &F : Fields) {
if (!F.getType().isNull() && F.getType()->isUnresolvedType()) {
setUnresolved();
break;
}
}
}
/// hasAnyDefaultValues - Return true if any of our elements has a default /// hasAnyDefaultValues - Return true if any of our elements has a default
/// value. /// value.
@@ -1392,8 +1383,6 @@ std::string TypeBase::getString() const {
void TypeBase::dump() const { void TypeBase::dump() const {
print(llvm::errs()); print(llvm::errs());
if (isUnresolvedType())
llvm::errs() << " [unresolved]";
llvm::errs() << '\n'; llvm::errs() << '\n';
} }

View File

@@ -1867,8 +1867,7 @@ Expr *ExprRewriter::coerceScalarToTuple(Expr *expr, TupleType *toTuple,
} }
if (i == toScalarIdx) { if (i == toScalarIdx) {
if (field.isVararg()) { if (field.isVararg()) {
assert((field.getVarargBaseTy()->isUnresolvedType() || assert(expr->getType()->isEqual(field.getVarargBaseTy()) &&
expr->getType()->isEqual(field.getVarargBaseTy())) &&
"scalar field is not equivalent to dest vararg field?!"); "scalar field is not equivalent to dest vararg field?!");
sugarFields.push_back(TupleTypeElt(field.getType(), sugarFields.push_back(TupleTypeElt(field.getType(),
@@ -1877,8 +1876,7 @@ Expr *ExprRewriter::coerceScalarToTuple(Expr *expr, TupleType *toTuple,
true)); true));
} }
else { else {
assert((field.getType()->isUnresolvedType() || assert(expr->getType()->isEqual(field.getType()) &&
expr->getType()->isEqual(field.getType())) &&
"scalar field is not equivalent to dest tuple field?!"); "scalar field is not equivalent to dest tuple field?!");
sugarFields.push_back(TupleTypeElt(expr->getType(), sugarFields.push_back(TupleTypeElt(expr->getType(),
field.getName())); field.getName()));

View File

@@ -672,7 +672,7 @@ public:
} }
void semaFuncExpr(FuncExpr *FE, bool isFirstPass) { void semaFuncExpr(FuncExpr *FE, bool isFirstPass) {
if (FE->getType() && !FE->getType()->isUnresolvedType()) if (FE->getType())
return; return;
bool badType = false; bool badType = false;

View File

@@ -543,15 +543,6 @@ void TypeChecker::typeCheckIgnoredExpr(Expr *E) {
void TypeChecker::typeCheckFunctionBody(FuncExpr *FE) { void TypeChecker::typeCheckFunctionBody(FuncExpr *FE) {
if (FE->getDecl() && FE->getDecl()->isInvalid()) if (FE->getDecl() && FE->getDecl()->isInvalid())
return; return;
// If this was a func() expression whose context did not fully infer types for
// the arguments, mark the argument types as error type.
if (FE->getType()->isUnresolvedType()) {
for (auto P : FE->getArgParamPatterns())
coerceToType(P, FE, ErrorType::get(Context));
for (auto P : FE->getBodyParamPatterns())
coerceToType(P, FE, ErrorType::get(Context));
}
BraceStmt *BS = FE->getBody(); BraceStmt *BS = FE->getBody();
if (!BS) if (!BS)

View File

@@ -1013,7 +1013,7 @@ void swift::performTypeChecking(TranslationUnit *TU, unsigned StartElem) {
// FIXME: I'm not sure this check is really correct. // FIXME: I'm not sure this check is really correct.
if (VD->getName().empty()) if (VD->getName().empty())
continue; continue;
if (VD->getType()->is<ErrorType>() || VD->getType()->isUnresolvedType()) if (VD->getType()->is<ErrorType>())
continue; continue;
auto &PrevOv = CheckOverloads[VD->getName()]; auto &PrevOv = CheckOverloads[VD->getName()];
if (i >= StartElem) { if (i >= StartElem) {