mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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())));
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -672,7 +672,7 @@ public:
|
||||
}
|
||||
|
||||
void semaFuncExpr(FuncExpr *FE, bool isFirstPass) {
|
||||
if (FE->getType() && !FE->getType()->isUnresolvedType())
|
||||
if (FE->getType())
|
||||
return;
|
||||
|
||||
bool badType = false;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user