Skip to content

Revert "AST: Make SubstFlags::UseErrorType the default behavior" #26804

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

Closed
Closed
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
19 changes: 9 additions & 10 deletions include/swift/AST/ProtocolConformance.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,13 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {

/// Retrieve the type witness for the given associated type.
Type getTypeWitness(AssociatedTypeDecl *assocType,
SubstOptions options=None) const;
SubstOptions options = None) const;

/// Retrieve the type witness and type decl (if one exists)
/// for the given associated type.
std::pair<Type, TypeDecl *>
getTypeWitnessAndDecl(AssociatedTypeDecl *assocType,
SubstOptions options=None) const;
SubstOptions options = None) const;

/// Apply the given function object to each type witness within this
/// protocol conformance.
Expand Down Expand Up @@ -311,14 +311,13 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {

/// Substitute the conforming type and produce a ProtocolConformance that
/// applies to the substituted type.
ProtocolConformance *subst(SubstitutionMap subMap,
SubstOptions options=None) const;
ProtocolConformance *subst(SubstitutionMap subMap) const;

/// Substitute the conforming type and produce a ProtocolConformance that
/// applies to the substituted type.
ProtocolConformance *subst(TypeSubstitutionFn subs,
LookupConformanceFn conformances,
SubstOptions options=None) const;
SubstOptions options = None) const;

void dump() const;
void dump(llvm::raw_ostream &out, unsigned indent = 0) const;
Expand Down Expand Up @@ -590,7 +589,7 @@ class NormalProtocolConformance : public RootProtocolConformance,
/// for the given associated type.
std::pair<Type, TypeDecl *>
getTypeWitnessAndDecl(AssociatedTypeDecl *assocType,
SubstOptions options=None) const;
SubstOptions options = None) const;

/// Determine whether the protocol conformance has a type witness for the
/// given associated type.
Expand Down Expand Up @@ -715,12 +714,12 @@ class SelfProtocolConformance : public RootProtocolConformance {

std::pair<Type, TypeDecl *>
getTypeWitnessAndDecl(AssociatedTypeDecl *assocType,
SubstOptions options=None) const {
SubstOptions options) const {
llvm_unreachable("self-conformances never have associated types");
}

Type getTypeWitness(AssociatedTypeDecl *assocType,
SubstOptions options=None) const {
SubstOptions options) const {
llvm_unreachable("self-conformances never have associated types");
}

Expand Down Expand Up @@ -861,7 +860,7 @@ class SpecializedProtocolConformance : public ProtocolConformance,
/// for the given associated type.
std::pair<Type, TypeDecl *>
getTypeWitnessAndDecl(AssociatedTypeDecl *assocType,
SubstOptions options=None) const;
SubstOptions options = None) const;

/// Given that the requirement signature of the protocol directly states
/// that the given dependent type must conform to the given protocol,
Expand Down Expand Up @@ -973,7 +972,7 @@ class InheritedProtocolConformance : public ProtocolConformance,
/// for the given associated type.
std::pair<Type, TypeDecl *>
getTypeWitnessAndDecl(AssociatedTypeDecl *assocType,
SubstOptions options=None) const {
SubstOptions options = None) const {
return InheritedConformance->getTypeWitnessAndDecl(assocType, options);
}

Expand Down
5 changes: 2 additions & 3 deletions include/swift/AST/ProtocolConformanceRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,13 @@ class ProtocolConformanceRef {

/// Apply a substitution to the conforming type.
ProtocolConformanceRef subst(Type origType,
SubstitutionMap subMap,
SubstOptions options=None) const;
SubstitutionMap subMap) const;

/// Apply a substitution to the conforming type.
ProtocolConformanceRef subst(Type origType,
TypeSubstitutionFn subs,
LookupConformanceFn conformances,
SubstOptions options=None) const;
SubstOptions options = None) const;

/// Map contextual types to interface types in the conformance.
ProtocolConformanceRef mapConformanceOutOfContext() const;
Expand Down
4 changes: 2 additions & 2 deletions include/swift/AST/Requirement.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ class Requirement {
template <typename... Args>
Optional<Requirement> subst(Args &&... args) const {
auto newFirst = getFirstType().subst(std::forward<Args>(args)...);
if (newFirst->hasError())
if (!newFirst)
return None;

switch (getKind()) {
case RequirementKind::Conformance:
case RequirementKind::Superclass:
case RequirementKind::SameType: {
auto newSecond = getSecondType().subst(std::forward<Args>(args)...);
if (newSecond->hasError())
if (!newSecond)
return None;
return Requirement(getKind(), newFirst, newSecond);
}
Expand Down
5 changes: 2 additions & 3 deletions include/swift/AST/SubstitutionMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,13 @@ class SubstitutionMap {

/// Apply a substitution to all replacement types in the map. Does not
/// change keys.
SubstitutionMap subst(SubstitutionMap subMap,
SubstOptions options=None) const;
SubstitutionMap subst(SubstitutionMap subMap) const;

/// Apply a substitution to all replacement types in the map. Does not
/// change keys.
SubstitutionMap subst(TypeSubstitutionFn subs,
LookupConformanceFn conformances,
SubstOptions options=None) const;
SubstOptions options = None) const;

/// Create a substitution map for a protocol conformance.
static SubstitutionMap
Expand Down
13 changes: 8 additions & 5 deletions include/swift/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,19 @@ class LookUpConformanceInSignature {

/// Flags that can be passed when substituting into a type.
enum class SubstFlags {
/// If a type cannot be produced because some member type is
/// missing, place an 'error' type into the position of the base.
UseErrorType = 0x01,
/// Allow substitutions to recurse into SILFunctionTypes.
/// Normally, SILType::subst() should be used for lowered
/// types, however in special cases where the substitution
/// is just changing between contextual and interface type
/// representations, using Type::subst() is allowed.
AllowLoweredTypes = 0x01,
AllowLoweredTypes = 0x02,
/// Map member types to their desugared witness type.
DesugarMemberTypes = 0x02,
DesugarMemberTypes = 0x04,
/// Substitute types involving opaque type archetypes.
SubstituteOpaqueArchetypes = 0x04,
SubstituteOpaqueArchetypes = 0x08,
};

/// Options for performing substitutions into a type.
Expand Down Expand Up @@ -292,7 +295,7 @@ class Type {
///
/// \returns the substituted type, or a null type if an error occurred.
Type subst(SubstitutionMap substitutions,
SubstOptions options=None) const;
SubstOptions options = None) const;

/// Replace references to substitutable types with new, concrete types and
/// return the substituted result.
Expand All @@ -307,7 +310,7 @@ class Type {
/// \returns the substituted type, or a null type if an error occurred.
Type subst(TypeSubstitutionFn substitutions,
LookupConformanceFn conformances,
SubstOptions options=None) const;
SubstOptions options = None) const;

/// Replace references to substitutable types with error types.
Type substDependentTypesWithErrorTypes() const;
Expand Down
4 changes: 2 additions & 2 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -2818,7 +2818,7 @@ class AnyFunctionType : public TypeBase {
return Param(getType(), Identifier(), getFlags().asParamFlags());
}

Yield subst(SubstitutionMap subs, SubstOptions options=None) const {
Yield subst(SubstitutionMap subs, SubstOptions options = None) const {
return Yield(getType().subst(subs, options), getFlags());
}

Expand All @@ -2839,7 +2839,7 @@ class AnyFunctionType : public TypeBase {
CanType getType() const { return CanType(Yield::getType()); }
CanParam asParam() const { return CanParam::getFromParam(Yield::asParam());}

CanYield subst(SubstitutionMap subs, SubstOptions options=None) const {
CanYield subst(SubstitutionMap subs, SubstOptions options = None) const {
return CanYield(getType().subst(subs, options)->getCanonicalType(),
getFlags());
}
Expand Down
14 changes: 8 additions & 6 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2227,11 +2227,14 @@ TypeAliasType *TypeAliasType::get(TypeAliasDecl *typealias, Type parent,
if (parent->hasTypeVariable())
storedProperties |= RecursiveTypeProperties::HasTypeVariable;
}

for (auto substGP : substitutions.getReplacementTypes()) {
properties |= substGP->getRecursiveProperties();
if (substGP->hasTypeVariable())
storedProperties |= RecursiveTypeProperties::HasTypeVariable;
auto genericSig = substitutions.getGenericSignature();
if (genericSig) {
for (Type gp : genericSig->getGenericParams()) {
auto substGP = gp.subst(substitutions, SubstFlags::UseErrorType);
properties |= substGP->getRecursiveProperties();
if (substGP->hasTypeVariable())
storedProperties |= RecursiveTypeProperties::HasTypeVariable;
}
}

// Figure out which arena this type will go into.
Expand All @@ -2249,7 +2252,6 @@ TypeAliasType *TypeAliasType::get(TypeAliasDecl *typealias, Type parent,
return result;

// Build a new type.
auto *genericSig = typealias->getGenericSignature();
auto size = totalSizeToAlloc<Type, SubstitutionMap>(parent ? 1 : 0,
genericSig ? 1 : 0);
auto mem = ctx.Allocate(size, alignof(TypeAliasType), arena);
Expand Down
9 changes: 8 additions & 1 deletion lib/AST/ASTDemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ Type ASTBuilder::createTypeAliasType(GenericTypeDecl *decl, Type parent) {

// FIXME: subst() should build the sugar for us
declaredType = declaredType.subst(subs);
if (!declaredType)
return Type();

return TypeAliasType::get(aliasDecl, parent, subs, declaredType);
}

Expand Down Expand Up @@ -248,7 +251,8 @@ Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl,

// FIXME: We're not checking that the type satisfies the generic
// requirements of the signature here.
return origType.subst(subs);
auto substType = origType.subst(subs);
return substType;
}

Type ASTBuilder::resolveOpaqueType(NodePointer opaqueDescriptor,
Expand Down Expand Up @@ -331,6 +335,9 @@ Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl,

// FIXME: subst() should build the sugar for us
auto declaredType = aliasDecl->getDeclaredInterfaceType().subst(subMap);
if (!declaredType)
return Type();

return TypeAliasType::get(aliasDecl, parent, subMap, declaredType);
}

Expand Down
9 changes: 4 additions & 5 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,8 @@ class PrintAST : public ASTVisitor<PrintAST> {
M, cast<ValueDecl>(Current));
}

T = T.subst(subMap, SubstFlags::DesugarMemberTypes);
T = T.subst(subMap,
SubstFlags::DesugarMemberTypes | SubstFlags::UseErrorType);
}

printTypeWithOptions(T, options);
Expand Down Expand Up @@ -1446,12 +1447,10 @@ void PrintAST::printSingleDepthOfGenericSignature(
second = req.getSecondType();

if (!subMap.empty()) {
Type subFirst = substParam(first);
if (!subFirst->hasError())
if (Type subFirst = substParam(first))
first = subFirst;
if (second) {
Type subSecond = substParam(second);
if (!subSecond->hasError())
if (Type subSecond = substParam(second))
second = subSecond;
if (!(first->is<ArchetypeType>() || first->isTypeParameter()) &&
!(second->is<ArchetypeType>() || second->isTypeParameter()))
Expand Down
3 changes: 2 additions & 1 deletion lib/AST/GenericEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ Type GenericEnvironment::mapTypeIntoContext(

Type result = type.subst(QueryInterfaceTypeSubstitutions(this),
lookupConformance,
SubstFlags::AllowLoweredTypes);
(SubstFlags::AllowLoweredTypes|
SubstFlags::UseErrorType));
assert((!result->hasTypeParameter() || result->hasError()) &&
"not fully substituted");
return result;
Expand Down
6 changes: 3 additions & 3 deletions lib/AST/GenericSignatureBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3817,7 +3817,7 @@ static Type substituteConcreteType(GenericSignatureBuilder &builder,
subMap = SubstitutionMap::getProtocolSubstitutions(
proto, parentType, ProtocolConformanceRef(proto));

type = type.subst(subMap);
type = type.subst(subMap, SubstFlags::UseErrorType);
} else {
// Substitute in the superclass type.
auto parentPA = basePA->getEquivalenceClassIfPresent();
Expand All @@ -3827,7 +3827,7 @@ static Type substituteConcreteType(GenericSignatureBuilder &builder,

subMap = parentType->getMemberSubstitutionMap(parentDecl->getParentModule(),
concreteDecl);
type = type.subst(subMap);
type = type.subst(subMap, SubstFlags::UseErrorType);
}

// If we had a typealias, form a sugared type.
Expand Down Expand Up @@ -5187,7 +5187,7 @@ GenericSignatureBuilder::addRequirement(const Requirement &req,
// Local substitution for types in the requirement.
auto subst = [&](Type t) {
if (subMap)
return t.subst(*subMap);
return t.subst(*subMap, SubstFlags::UseErrorType);

return t;
};
Expand Down
Loading