Skip to content

Error type cleanup #18392

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 6 commits into from
Jul 31, 2018
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
7 changes: 0 additions & 7 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4392,13 +4392,6 @@ class AbstractStorageDecl : public ValueDecl {
/// property from the given module?
bool isResilient(ModuleDecl *M, ResilienceExpansion expansion) const;

/// Returns the interface type of elements of storage represented by this
/// declaration.
///
/// For variables, this is the type of the variable itself.
/// For subscripts, this is the type of the subscript element.
Type getStorageInterfaceType() const;

/// Does the storage use a behavior?
bool hasBehavior() const {
return BehaviorInfo.getPointer() != nullptr;
Expand Down
2 changes: 2 additions & 0 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3528,6 +3528,8 @@ getGenericFunctionRecursiveProperties(Type Input, Type Result) {
static_assert(RecursiveTypeProperties::BitWidth == 10,
"revisit this if you add new recursive type properties");
RecursiveTypeProperties properties;
if (Input->getRecursiveProperties().hasError())
properties |= RecursiveTypeProperties::HasError;
if (Result->getRecursiveProperties().hasDynamicSelf())
properties |= RecursiveTypeProperties::HasDynamicSelf;
if (Result->getRecursiveProperties().hasError())
Expand Down
15 changes: 8 additions & 7 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4335,7 +4335,7 @@ SourceLoc AbstractStorageDecl::getOverrideLoc() const {

Type AbstractStorageDecl::getValueInterfaceType() const {
if (auto var = dyn_cast<VarDecl>(this))
return var->getInterfaceType();
return var->getInterfaceType()->getReferenceStorageReferent();
return cast<SubscriptDecl>(this)->getElementInterfaceType();
}

Expand Down Expand Up @@ -5296,11 +5296,12 @@ void AbstractFunctionDecl::computeType(AnyFunctionType::ExtInfo info) {
} else if (auto ctor = dyn_cast<ConstructorDecl>(this)) {
auto *dc = ctor->getDeclContext();

if (hasSelf)
resultTy = dc->getSelfInterfaceType();

if (!resultTy)
resultTy = ErrorType::get(ctx);
if (hasSelf) {
if (!dc->isTypeContext())
resultTy = ErrorType::get(ctx);
else
resultTy = dc->getSelfInterfaceType();
}

// Adjust result type for failability.
if (ctor->getFailability() != OTK_None)
Expand Down Expand Up @@ -5514,7 +5515,7 @@ Type FuncDecl::getResultInterfaceType() const {
return nullptr;

Type resultTy = getInterfaceType();
if (resultTy->hasError())
if (resultTy->is<ErrorType>())
return resultTy;

if (hasImplicitSelfDecl())
Expand Down
12 changes: 0 additions & 12 deletions lib/AST/NameLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1511,18 +1511,6 @@ void ClassDecl::recordObjCMethod(AbstractFunctionDecl *method) {
vec.push_back(method);
}

Type AbstractStorageDecl::getStorageInterfaceType() const {
if (auto var = dyn_cast<VarDecl>(this)) {
return var->getInterfaceType();
}

if (auto sub = dyn_cast<SubscriptDecl>(this)) {
return sub->getElementInterfaceType();
}

llvm_unreachable("unhandled storage decl kind");
}

/// Configure name lookup for the given declaration context and options.
///
/// This utility is used by qualified name lookup.
Expand Down
3 changes: 1 addition & 2 deletions lib/ClangImporter/ImporterImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -626,8 +626,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
assert(CD->getInterfaceType());
ty = CD->getResultInterfaceType();
} else {
ty = cast<AbstractStorageDecl>(decl)->getValueInterfaceType()
->getReferenceStorageReferent();
ty = cast<AbstractStorageDecl>(decl)->getValueInterfaceType();
}
#endif

Expand Down
3 changes: 1 addition & 2 deletions lib/SIL/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4783,8 +4783,7 @@ void SILProperty::verify(const SILModule &M) const {
auto sig = dc->getGenericSignatureOfContext();
auto baseTy = dc->getInnermostTypeContext()->getSelfInterfaceType()
->getCanonicalType(sig);
auto leafTy = decl->getStorageInterfaceType()->getReferenceStorageReferent()
->getCanonicalType(sig);
auto leafTy = decl->getValueInterfaceType()->getCanonicalType(sig);
SubstitutionMap subs;
if (sig) {
auto env = dc->getGenericEnvironmentOfContext();
Expand Down
9 changes: 4 additions & 5 deletions lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1202,14 +1202,13 @@ TypeConverter::canStorageUseStoredKeyPathComponent(AbstractStorageDecl *decl) {
M.getSwiftModule());
switch (strategy.getKind()) {
case AccessStrategy::Storage: {
// If the stored value would need to be reabstracted in fully opaque
// context, then we have to treat the component as computed.
auto componentObjTy = decl->getStorageInterfaceType()
->getWithoutSpecifierType();
// Keypaths rely on accessors to handle the special behavior of weak or
// unowned properties.
if (componentObjTy->is<ReferenceStorageType>())
if (decl->getInterfaceType()->is<ReferenceStorageType>())
return false;
// If the stored value would need to be reabstracted in fully opaque
// context, then we have to treat the component as computed.
auto componentObjTy = decl->getValueInterfaceType();
if (auto genericEnv =
decl->getInnermostDeclContext()->getGenericEnvironmentOfContext())
componentObjTy = genericEnv->mapTypeIntoContext(componentObjTy);
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3681,7 +3681,7 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
if (auto var = dyn_cast<VarDecl>(storage)) {
CanType componentTy;
if (!var->getDeclContext()->isTypeContext()) {
componentTy = storage->getStorageInterfaceType()->getCanonicalType();
componentTy = var->getInterfaceType()->getCanonicalType();
} else {
componentTy =
GenericEnvironment::mapTypeIntoContext(genericEnv, baseTy)
Expand Down
3 changes: 1 addition & 2 deletions lib/Sema/CodeSynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2169,8 +2169,7 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,

auto varType = var->getType()
->getReferenceStorageReferent();
auto varInterfaceType = var->getInterfaceType()
->getReferenceStorageReferent();
auto varInterfaceType = var->getValueInterfaceType();

// If var is a lazy property, its value is provided for the underlying
// storage. We thus take an optional of the properties type. We only
Expand Down
41 changes: 30 additions & 11 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2620,6 +2620,12 @@ class DeclChecker : public DeclVisitor<DeclChecker> {

void visitSubscriptDecl(SubscriptDecl *SD) {
TC.validateDecl(SD);

if (!SD->isInvalid()) {
TC.checkReferencedGenericParams(SD);
TC.checkProtocolSelfRequirements(SD);
}

TC.checkDeclAttributes(SD);

AccessControlChecker::checkAccessControl(TC, SD);
Expand Down Expand Up @@ -3121,6 +3127,15 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
void visitFuncDecl(FuncDecl *FD) {
TC.validateDecl(FD);

// We get bogus errors here with generic subscript materializeForSet.
if (!FD->isInvalid()) {
if (!isa<AccessorDecl>(FD) ||
!cast<AccessorDecl>(FD)->isMaterializeForSet()) {
TC.checkReferencedGenericParams(FD);
TC.checkProtocolSelfRequirements(FD);
}
}

AccessControlChecker::checkAccessControl(TC, FD);
UsableFromInlineChecker::checkUsableFromInline(TC, FD);

Expand Down Expand Up @@ -3265,6 +3280,11 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
void visitConstructorDecl(ConstructorDecl *CD) {
TC.validateDecl(CD);

if (!CD->isInvalid()) {
TC.checkReferencedGenericParams(CD);
TC.checkProtocolSelfRequirements(CD);
}

// Check whether this initializer overrides an initializer in its
// superclass.
if (!checkOverrides(CD)) {
Expand Down Expand Up @@ -3609,13 +3629,13 @@ void checkMemberOperator(TypeChecker &TC, FuncDecl *FD) {
isProtocol, FD->getFullName());
}

bool checkDynamicSelfReturn(TypeChecker &TC, FuncDecl *func,
bool checkDynamicSelfReturn(FuncDecl *func,
TypeRepr *typeRepr,
unsigned optionalDepth) {
// Look through parentheses.
if (auto parenRepr = dyn_cast<TupleTypeRepr>(typeRepr)) {
if (!parenRepr->isParenType()) return false;
return checkDynamicSelfReturn(TC, func, parenRepr->getElementType(0),
return checkDynamicSelfReturn(func, parenRepr->getElementType(0),
optionalDepth);
}

Expand All @@ -3624,8 +3644,9 @@ bool checkDynamicSelfReturn(TypeChecker &TC, FuncDecl *func,
TypeAttributes attrs = attrRepr->getAttrs();
if (!attrs.empty())
return false;
return checkDynamicSelfReturn(TC, func, attrRepr->getTypeRepr(),
return checkDynamicSelfReturn(func, attrRepr->getTypeRepr(),
optionalDepth);

}

// Look through optional types.
Expand All @@ -3639,7 +3660,7 @@ bool checkDynamicSelfReturn(TypeChecker &TC, FuncDecl *func,
if (base) {
// But only one level.
if (optionalDepth != 0) return false;
return checkDynamicSelfReturn(TC, func, base, optionalDepth + 1);
return checkDynamicSelfReturn(func, base, optionalDepth + 1);
}

// Check whether we have a simple identifier type.
Expand All @@ -3648,17 +3669,16 @@ bool checkDynamicSelfReturn(TypeChecker &TC, FuncDecl *func,
return false;

// Check whether it is 'Self'.
if (simpleRepr->getIdentifier() != TC.Context.Id_Self)
if (simpleRepr->getIdentifier() != func->getASTContext().Id_Self)
return false;

// Note that the function has a dynamic Self return type and set
// the return type component to the dynamic self type.
func->setDynamicSelf(true);
return false;
return true;
}

/// Check for methods that return 'DynamicResult'.
bool checkDynamicSelfReturn(TypeChecker &TC, FuncDecl *func) {
bool checkDynamicSelfReturn(FuncDecl *func) {
// Check whether we have a specified result type.
auto typeRepr = func->getBodyResultTypeLoc().getTypeRepr();
if (!typeRepr)
Expand All @@ -3674,7 +3694,7 @@ bool checkDynamicSelfReturn(TypeChecker &TC, FuncDecl *func) {
if (isa<AccessorDecl>(func))
return false;

return checkDynamicSelfReturn(TC, func, typeRepr, 0);
return checkDynamicSelfReturn(func, typeRepr, 0);
}

Type buildAddressorResultType(TypeChecker &TC,
Expand Down Expand Up @@ -4097,8 +4117,7 @@ void TypeChecker::validateDecl(ValueDecl *D) {
validateSelfAccessKind(*this, FD);

// Check whether the return type is dynamic 'Self'.
if (checkDynamicSelfReturn(*this, FD))
FD->setInvalid();
FD->setDynamicSelf(checkDynamicSelfReturn(FD));

// Accessors should pick up various parts of their type signatures
// directly from the storage declaration instead of re-deriving them.
Expand Down
56 changes: 17 additions & 39 deletions lib/Sema/TypeCheckGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,13 +602,12 @@ static bool isSelfDerivedOrConcrete(Type protoSelf, Type type) {

// For a generic requirement in a protocol, make sure that the requirement
// set didn't add any requirements to Self or its associated types.
static bool checkProtocolSelfRequirements(GenericSignature *sig,
ValueDecl *decl,
TypeChecker &TC) {
void TypeChecker::checkProtocolSelfRequirements(ValueDecl *decl) {
// For a generic requirement in a protocol, make sure that the requirement
// set didn't add any requirements to Self or its associated types.
if (auto *proto = dyn_cast<ProtocolDecl>(decl->getDeclContext())) {
auto protoSelf = proto->getSelfInterfaceType();
auto *sig = decl->getInnermostDeclContext()->getGenericSignatureOfContext();
for (auto req : sig->getRequirements()) {
// If one of the types in the requirement is dependent on a non-Self
// type parameter, this requirement is okay.
Expand All @@ -622,27 +621,21 @@ static bool checkProtocolSelfRequirements(GenericSignature *sig,
req.getFirstType()->is<GenericTypeParamType>())
continue;

TC.diagnose(decl,
TC.Context.LangOpts.EffectiveLanguageVersion[0] >= 4
? diag::requirement_restricts_self
: diag::requirement_restricts_self_swift3,
decl->getDescriptiveKind(), decl->getFullName(),
req.getFirstType().getString(),
static_cast<unsigned>(req.getKind()),
req.getSecondType().getString());

if (TC.Context.LangOpts.EffectiveLanguageVersion[0] >= 4)
return true;
diagnose(decl,
Context.isSwiftVersion3()
? diag::requirement_restricts_self_swift3
: diag::requirement_restricts_self,
decl->getDescriptiveKind(), decl->getFullName(),
req.getFirstType().getString(),
static_cast<unsigned>(req.getKind()),
req.getSecondType().getString());
}
}

return false;
}

/// All generic parameters of a generic function must be referenced in the
/// declaration's type, otherwise we have no way to infer them.
static void checkReferencedGenericParams(GenericContext *dc,
TypeChecker &TC) {
void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
auto *genericParams = dc->getGenericParams();
auto *genericSig = dc->getGenericSignatureOfContext();
if (!genericParams)
Expand Down Expand Up @@ -798,9 +791,9 @@ static void checkReferencedGenericParams(GenericContext *dc,
continue;
}
// Produce an error that this generic parameter cannot be bound.
TC.diagnose(paramDecl->getLoc(), diag::unreferenced_generic_parameter,
paramDecl->getNameStr());
decl->setInterfaceType(ErrorType::get(TC.Context));
diagnose(paramDecl->getLoc(), diag::unreferenced_generic_parameter,
paramDecl->getNameStr());
decl->setInterfaceType(ErrorType::get(Context));
decl->setInvalid();
}
}
Expand Down Expand Up @@ -868,9 +861,6 @@ void TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
if (checkGenericFuncSignature(*this, nullptr, func, completeResolver))
invalid = true;

if (!invalid)
invalid = checkProtocolSelfRequirements(sig, func, *this);

if (invalid) {
func->setInterfaceType(ErrorType::get(Context));
func->setInvalid();
Expand All @@ -879,15 +869,9 @@ void TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {

func->computeType();

// We get bogus errors here with generic subscript materializeForSet.
if (!isa<AccessorDecl>(func) ||
!cast<AccessorDecl>(func)->isMaterializeForSet())
checkReferencedGenericParams(func, *this);

// Make sure that there are no unresolved
// dependent types in the generic signature.
assert(func->getInterfaceType()->hasError() ||
!func->getInterfaceType()->findUnresolvedDependentMemberType());
// Make sure that there are no unresolved dependent types in the
// generic signature.
assert(!func->getInterfaceType()->findUnresolvedDependentMemberType());
}

///
Expand Down Expand Up @@ -1010,10 +994,6 @@ TypeChecker::validateGenericSubscriptSignature(SubscriptDecl *subscript) {
CompleteGenericTypeResolver completeResolver(*this, sig);
if (checkGenericSubscriptSignature(*this, nullptr, subscript, completeResolver))
invalid = true;

if (!invalid)
invalid = checkProtocolSelfRequirements(sig, subscript, *this);

if (invalid) {
subscript->setInterfaceType(ErrorType::get(Context));
subscript->setInvalid();
Expand All @@ -1022,8 +1002,6 @@ TypeChecker::validateGenericSubscriptSignature(SubscriptDecl *subscript) {
}

subscript->computeType();

checkReferencedGenericParams(subscript, *this);
}

///
Expand Down
8 changes: 8 additions & 0 deletions lib/Sema/TypeChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,14 @@ class TypeChecker final : public LazyResolver {
/// of a generic subscript.
void validateGenericSubscriptSignature(SubscriptDecl *subscript);

/// For a generic requirement in a protocol, make sure that the requirement
/// set didn't add any requirements to Self or its associated types.
void checkProtocolSelfRequirements(ValueDecl *decl);

/// All generic parameters of a generic function must be referenced in the
/// declaration's type, otherwise we have no way to infer them.
void checkReferencedGenericParams(GenericContext *dc);

/// Construct a new generic environment for the given declaration context.
///
/// \param genericParams The generic parameters to validate.
Expand Down
1 change: 0 additions & 1 deletion test/Parse/init_deinit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ struct FooStructConstructorB {
struct FooStructConstructorC {
init {} // expected-error {{expected '('}}{{7-7=()}}
init<T> {} // expected-error {{expected '('}} {{10-10=()}}
// expected-error@-1{{generic parameter 'T' is not used in function signature}}
init? { self.init() } // expected-error {{expected '('}} {{8-8=()}}
}

Expand Down
Loading