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

View File

@@ -481,19 +481,9 @@ BoundGenericType::BoundGenericType(TypeKind theKind,
ArrayRef<Type> genericArgs,
ASTContext *context,
bool hasTypeVariable)
: TypeBase(theKind, context, /*Unresolved=*/false,
hasTypeVariable),
: TypeBase(theKind, context, hasTypeVariable),
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,
@@ -695,7 +685,7 @@ MetaTypeType *MetaTypeType::get(Type T, ASTContext &C) {
}
MetaTypeType::MetaTypeType(Type T, ASTContext *C, bool HasTypeVariable)
: TypeBase(TypeKind::MetaType, C, T->isUnresolvedType(), HasTypeVariable),
: TypeBase(TypeKind::MetaType, C, HasTypeVariable),
InstanceType(T) {
}
@@ -745,7 +735,6 @@ FunctionType::FunctionType(Type input, Type output,
(input->isCanonical() && output->isCanonical()) ?
&input->getASTContext() : 0,
input, output,
(input->isUnresolvedType() || output->isUnresolvedType()),
hasTypeVariable,
isThin,
cc),
@@ -777,7 +766,6 @@ PolymorphicFunctionType::PolymorphicFunctionType(Type input, Type output,
: AnyFunctionType(TypeKind::PolymorphicFunction,
(input->isCanonical() && output->isCanonical()) ?&C : 0,
input, output,
(input->isUnresolvedType() || output->isUnresolvedType()),
/*HasTypeVariable=*/false,
isThin, cc),
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)
: TypeBase(TypeKind::Array,
base->isCanonical() ? &base->getASTContext() : 0,
base->isUnresolvedType(), hasTypeVariable),
hasTypeVariable),
Base(base), Size(size) {}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -544,15 +544,6 @@ void TypeChecker::typeCheckFunctionBody(FuncExpr *FE) {
if (FE->getDecl() && FE->getDecl()->isInvalid())
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();
if (!BS)
return;

View File

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