Skip to content

Push ValueDecl::{has,get,set}Type() down to VarDecl #6018

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
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
8 changes: 0 additions & 8 deletions include/swift/AST/AnyFunctionRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,6 @@ class AnyFunctionRef {
}

Type getType() const {
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>())
return AFD->getType();
return TheFunction.get<AbstractClosureExpr *>()->getType();
}

/// FIXME: This should just be getType() when interface types take over in
/// the AST.
Type getInterfaceType() const {
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>())
return AFD->getInterfaceType();
return TheFunction.get<AbstractClosureExpr *>()->getType();
Expand Down
40 changes: 22 additions & 18 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1999,15 +1999,6 @@ class ValueDecl : public Decl {
SourceLoc getNameLoc() const { return NameLoc; }
SourceLoc getLoc() const { return NameLoc; }

bool hasType() const;
Type getType() const;

/// Set the type of this declaration for the first time.
void setType(Type T);

/// Overwrite the type of this declaration.
void overwriteType(Type T);

bool hasAccessibility() const {
return TypeAndAccess.getInt().hasValue();
}
Expand Down Expand Up @@ -2080,15 +2071,10 @@ class ValueDecl : public Decl {
/// If \p DC is null, returns true only if this declaration is public.
bool isAccessibleFrom(const DeclContext *DC) const;

/// Retrieve the "interface" type of this value, which is the type used when
/// the declaration is viewed from the outside. For a generic function,
/// this will have generic function type using generic parameters rather than
/// archetypes, while a generic nominal type's interface type will be the
/// generic type specialized with its generic parameters.
///
/// FIXME: Eventually, this will simply become the type of the value, and
/// we will substitute in the appropriate archetypes within a particular
/// context.
/// Retrieve the "interface" type of this value, which uses
/// GenericTypeParamType if the declaration is generic. For a generic
/// function, this will have a GenericFunctionType with a
/// GenericSignature inside the type.
Type getInterfaceType() const;
bool hasInterfaceType() const;

Expand Down Expand Up @@ -4080,6 +4066,8 @@ class VarDecl : public AbstractStorageDecl {
/// This is the type specified, including location information.
TypeLoc typeLoc;

Type typeInContext;

public:
VarDecl(bool IsStatic, bool IsLet, SourceLoc NameLoc, Identifier Name,
Type Ty, DeclContext *DC)
Expand All @@ -4098,6 +4086,22 @@ class VarDecl : public AbstractStorageDecl {
TypeLoc &getTypeLoc() { return typeLoc; }
TypeLoc getTypeLoc() const { return typeLoc; }

bool hasType() const {
return !!typeInContext;
}

/// Get the type of the variable within its context. If the context is generic,
/// this will use archetypes.
Type getType() const {
assert(typeInContext && "No context type set yet");
return typeInContext;
}

/// Set the type of the variable within its context.
void setType(Type t);

void markInvalid();

/// Retrieve the source range of the variable type, or an invalid range if the
/// variable's type is not explicitly written in the source.
///
Expand Down
9 changes: 3 additions & 6 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,13 +514,10 @@ namespace {
if (GenericTypeDecl *GTD = dyn_cast<GenericTypeDecl>(VD))
printGenericParameters(OS, GTD->getGenericParams());

if (!isa<AbstractFunctionDecl>(VD) &&
!isa<EnumElementDecl>(VD) &&
!isa<SubscriptDecl>(VD) &&
!isa<TypeDecl>(VD)) {
if (auto *var = dyn_cast<VarDecl>(VD)) {
OS << " type='";
if (VD->hasType())
VD->getType().print(OS);
if (var->hasType())
var->getType().print(OS);
else
OS << "<null type>";
OS << '\'';
Expand Down
42 changes: 0 additions & 42 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3215,48 +3215,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
ASTPrinter &Printer;
const PrintOptions &Options;

void printDeclContext(DeclContext *DC) {
switch (DC->getContextKind()) {
case DeclContextKind::Module: {
Module *M = cast<Module>(DC);

if (auto Parent = M->getParent())
printDeclContext(Parent);
Printer.printModuleRef(M, M->getName());
return;
}

case DeclContextKind::FileUnit:
printDeclContext(DC->getParent());
return;

case DeclContextKind::AbstractClosureExpr:
// FIXME: print closures somehow.
return;

case DeclContextKind::GenericTypeDecl:
visit(cast<GenericTypeDecl>(DC)->getType());
return;

case DeclContextKind::ExtensionDecl:
visit(cast<ExtensionDecl>(DC)->getExtendedType());
return;

case DeclContextKind::Initializer:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::SerializedLocal:
llvm_unreachable("bad decl context");

case DeclContextKind::AbstractFunctionDecl:
visit(cast<AbstractFunctionDecl>(DC)->getType());
return;

case DeclContextKind::SubscriptDecl:
visit(cast<SubscriptDecl>(DC)->getType());
return;
}
}

void printGenericArgs(ArrayRef<Type> Args) {
if (Args.empty())
return;
Expand Down
7 changes: 0 additions & 7 deletions lib/AST/ASTVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2410,13 +2410,6 @@ struct ASTNodeBase {};
abort();
}

void checkIsTypeOfRValue(ValueDecl *D, Type rvalueType, const char *what) {
auto declType = D->getType();
if (auto refType = declType->getAs<ReferenceStorageType>())
declType = refType->getReferentType();
checkSameType(declType, rvalueType, what);
}

void checkSameType(Type T0, Type T1, const char *what) {
if (T0->getCanonicalType() == T1->getCanonicalType())
return;
Expand Down
62 changes: 18 additions & 44 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1644,47 +1644,11 @@ ValueDecl::getSatisfiedProtocolRequirements(bool Sorted) const {
return NTD->getSatisfiedProtocolRequirementsForMember(this, Sorted);
}

bool ValueDecl::hasType() const {
assert(!isa<AbstractFunctionDecl>(this) &&
!isa<EnumElementDecl>(this) &&
!isa<SubscriptDecl>(this) &&
!isa<TypeDecl>(this) &&
"functions and enum case constructors only have an interface type");
return !TypeAndAccess.getPointer().isNull();
}

Type ValueDecl::getType() const {
assert(!isa<AbstractFunctionDecl>(this) &&
!isa<EnumElementDecl>(this) &&
!isa<SubscriptDecl>(this) &&
!isa<TypeDecl>(this) &&
"functions and enum case constructors only have an interface type");
assert(hasType() && "declaration has no type set yet");
return TypeAndAccess.getPointer();
}

void ValueDecl::setType(Type T) {
assert(!hasType() && "changing type of declaration");
overwriteType(T);
}

void ValueDecl::overwriteType(Type T) {
assert(!isa<AbstractFunctionDecl>(this) &&
!isa<EnumElementDecl>(this) &&
!isa<SubscriptDecl>(this) &&
!isa<TypeDecl>(this) &&
"functions and enum case constructors only have an interface type");

TypeAndAccess.setPointer(T);
if (!T.isNull() && T->hasError())
setInvalid();
}

bool ValueDecl::hasInterfaceType() const {
// getInterfaceType() returns the contextual type for ParamDecls which
// don't have an explicit interface type.
if (isa<ParamDecl>(this))
return hasType();
if (auto *PD = dyn_cast<ParamDecl>(this))
return PD->hasType();

return !!InterfaceTy;
}
Expand All @@ -1693,14 +1657,11 @@ Type ValueDecl::getInterfaceType() const {
if (InterfaceTy)
return InterfaceTy;

if (!hasType())
return Type();

// FIXME: ParamDecls are funky and don't always have an interface type
if (isa<ParamDecl>(this))
return getType();
if (auto *PD = dyn_cast<ParamDecl>(this))
return PD->getType();

llvm_unreachable("decl has context type but no interface type");
llvm_unreachable("no interface type was set");
}

void ValueDecl::setInterfaceType(Type type) {
Expand Down Expand Up @@ -3407,6 +3368,19 @@ static bool isSettable(const AbstractStorageDecl *decl) {
llvm_unreachable("bad storage kind");
}

void VarDecl::setType(Type t) {
typeInContext = t;
if (t && t->hasError())
setInvalid();
}

void VarDecl::markInvalid() {
auto &Ctx = getASTContext();
setType(ErrorType::get(Ctx));
setInterfaceType(ErrorType::get(Ctx));
setInvalid();
}

/// \brief Returns whether the var is settable in the specified context: this
/// is either because it is a stored var, because it has a custom setter, or
/// is a let member in an initializer.
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/DeclContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ unsigned DeclContext::printContext(raw_ostream &OS, unsigned indent) const {
auto *SD = cast<SubscriptDecl>(this);
OS << " name=" << SD->getName();
if (SD->hasInterfaceType())
OS << " : " << SD->getType();
OS << " : " << SD->getInterfaceType();
else
OS << " : (no type set)";
break;
Expand Down
3 changes: 2 additions & 1 deletion lib/AST/LookupVisibleDecls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,9 @@ static void doDynamicLookup(VisibleDeclConsumer &Consumer,
}

case DeclKind::Var: {
auto *VD = cast<VarDecl>(D);
auto Signature =
std::make_pair(D->getName(), D->getType()->getCanonicalType());
std::make_pair(VD->getName(), VD->getType()->getCanonicalType());
if (!PropertiesReported.insert(Signature).second)
return;
break;
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Mangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,7 @@ void Mangler::mangleType(Type type, unsigned uncurryLevel) {
SmallVector<const void *, 4> SortedSubsts(Substitutions.size());
for (auto S : Substitutions) SortedSubsts[S.second] = S.first;
for (auto S : SortedSubsts) ContextMangler.addSubstitution(S);
while (DC && DC->getGenericParamsOfContext()) {
while (DC && DC->isGenericContext()) {
if (DC->isInnermostContextGeneric() &&
DC->getGenericParamsOfContext()->getDepth() == GTPT->getDepth())
break;
Expand Down
6 changes: 3 additions & 3 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1468,7 +1468,7 @@ static bool addErrorDomain(NominalTypeDecl *swiftDecl,
false));
auto stringTy = C.getStringDecl()->getDeclaredType();
assert(stringTy && "no string type available");
if (!swiftValueDecl || !swiftValueDecl->getType()->isEqual(stringTy)) {
if (!swiftValueDecl || !swiftValueDecl->getInterfaceType()->isEqual(stringTy)) {
// Couldn't actually import it as an error enum, fall back to enum
return false;
}
Expand Down Expand Up @@ -1639,13 +1639,13 @@ applyPropertyOwnership(VarDecl *prop,
}
if (attrs & clang::ObjCPropertyDecl::OBJC_PR_weak) {
prop->getAttrs().add(new (ctx) OwnershipAttr(Ownership::Weak));
prop->overwriteType(WeakStorageType::get(prop->getType(), ctx));
prop->setType(WeakStorageType::get(prop->getType(), ctx));
return;
}
if ((attrs & clang::ObjCPropertyDecl::OBJC_PR_assign) ||
(attrs & clang::ObjCPropertyDecl::OBJC_PR_unsafe_unretained)) {
prop->getAttrs().add(new (ctx) OwnershipAttr(Ownership::Unmanaged));
prop->overwriteType(UnmanagedStorageType::get(prop->getType(), ctx));
prop->setType(UnmanagedStorageType::get(prop->getType(), ctx));
return;
}
}
Expand Down
7 changes: 5 additions & 2 deletions lib/SIL/SILFunctionType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,8 +763,11 @@ static CanSILFunctionType getSILFunctionType(SILModule &M,
}

auto *VD = capture.getDecl();
auto type = ArchetypeBuilder::mapTypeOutOfContext(
function->getAsDeclContext(), VD->getType());
auto type = VD->getInterfaceType();
// FIXME: Interface types for parameters
if (type->hasArchetype())
type = ArchetypeBuilder::mapTypeOutOfContext(
function->getAsDeclContext(), type);
auto canType = getCanonicalType(type);

auto &loweredTL = Types.getTypeLowering(
Expand Down
21 changes: 13 additions & 8 deletions lib/SILGen/SILGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,13 +266,14 @@ void SILGenFunction::emitCaptures(SILLocation loc,
// let declarations.
auto Entry = VarLocs[vd];

auto &tl = getTypeLowering(vd->getType()->getReferenceStorageReferent());
auto *var = cast<VarDecl>(vd);
auto &tl = getTypeLowering(var->getType()->getReferenceStorageReferent());
SILValue Val = Entry.value;

if (!Val->getType().isAddress()) {
// Our 'let' binding can guarantee the lifetime for the callee,
// if we don't need to do anything more to it.
if (canGuarantee && !vd->getType()->is<ReferenceStorageType>()) {
if (canGuarantee && !var->getType()->is<ReferenceStorageType>()) {
auto guaranteed = ManagedValue::forUnmanaged(Val);
capturedArgs.push_back(guaranteed);
break;
Expand All @@ -289,8 +290,8 @@ void SILGenFunction::emitCaptures(SILLocation loc,
// If we're capturing an unowned pointer by value, we will have just
// loaded it into a normal retained class pointer, but we capture it as
// an unowned pointer. Convert back now.
if (vd->getType()->is<ReferenceStorageType>()) {
auto type = getTypeLowering(vd->getType()).getLoweredType();
if (var->getType()->is<ReferenceStorageType>()) {
auto type = getTypeLowering(var->getType()).getLoweredType();
Val = emitConversionFromSemanticValue(loc, Val, type);
}

Expand Down Expand Up @@ -700,12 +701,15 @@ static void forwardCaptureArgs(SILGenFunction &gen,
case CaptureKind::None:
break;

case CaptureKind::Constant:
addSILArgument(gen.getLoweredType(vd->getType()), vd);
case CaptureKind::Constant: {
auto *var = dyn_cast<VarDecl>(vd);
addSILArgument(gen.getLoweredType(var->getType()), vd);
break;
}

case CaptureKind::Box: {
SILType ty = gen.getLoweredType(vd->getType()->getRValueType())
auto *var = dyn_cast<VarDecl>(vd);
SILType ty = gen.getLoweredType(var->getType()->getRValueType())
.getAddressType();
// Forward the captured owning box.
SILType boxTy = SILType::getPrimitiveObjectType(
Expand All @@ -715,7 +719,8 @@ static void forwardCaptureArgs(SILGenFunction &gen,
}

case CaptureKind::StorageAddress: {
SILType ty = gen.getLoweredType(vd->getType()->getRValueType())
auto *var = dyn_cast<VarDecl>(vd);
SILType ty = gen.getLoweredType(var->getType()->getRValueType())
.getAddressType();
// Forward the captured value address.
addSILArgument(ty, vd);
Expand Down
Loading