Skip to content

Remove -enable-experimental-nested-generic-types flag #5600

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 8 commits into from
Nov 18, 2016
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
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,26 @@ CHANGELOG
Swift 3.1
---------

* [SR-1446](https://bugs.swift.org/browse/SR-1446)

Nested types may now appear inside generic types, and nested types may have their own generic parameters:

```swift
struct OuterNonGeneric {
struct InnerGeneric<T> {}
}

struct OuterGeneric<T> {
struct InnerNonGeneric {}

struct InnerGeneric<T> {}
}

extension OuterNonGeneric.InnerGeneric {}
extension OuterGeneric.InnerNonGeneric {}
extension OuterGeneric.InnerGeneric {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I constrain the outer generic parameter? (if it has a different name)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep

```

* [SR-1009](https://bugs.swift.org/browse/SR-1009):

Constrained extensions allow same-type constraints between generic parameters and concrete types. This enables you to create extensions, for example, on `Array` with `Int` elements:
Expand Down
9 changes: 0 additions & 9 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1144,15 +1144,6 @@ ERROR(pattern_binds_no_variables,none,


// Generic types
ERROR(unsupported_generic_nested_in_type,none,
"generic type %0 cannot be nested in type %1",
(Identifier, Identifier))
ERROR(unsupported_type_nested_in_generic_type,none,
"type %0 cannot be nested in generic type %1",
(Identifier, Identifier))
ERROR(unsupported_type_nested_in_generic_extension,none,
"type %0 cannot be nested in extension of generic type %1",
(Identifier, Identifier))
ERROR(unsupported_type_nested_in_generic_function,none,
"type %0 cannot be nested in generic function %1",
(Identifier, Identifier))
Expand Down
3 changes: 0 additions & 3 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,6 @@ namespace swift {
/// \brief Enable experimental property behavior feature.
bool EnableExperimentalPropertyBehaviors = false;

/// \brief Enable experimental nested generic types feature.
bool EnableExperimentalNestedGenericTypes = false;

/// \brief Staging flag for class resilience, which we do not want to enable
/// fully until more code is in place, to allow the standard library to be
/// tested with value type resilience only.
Expand Down
4 changes: 0 additions & 4 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,6 @@ def enable_experimental_property_behaviors :
Flag<["-"], "enable-experimental-property-behaviors">,
HelpText<"Enable experimental property behaviors">;

def enable_experimental_nested_generic_types :
Flag<["-"], "enable-experimental-nested-generic-types">,
HelpText<"Enable experimental support for nested generic types">;

def disable_availability_checking : Flag<["-"],
"disable-availability-checking">,
HelpText<"Disable checking for potentially unavailable APIs">;
Expand Down
20 changes: 15 additions & 5 deletions lib/Basic/Demangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2396,6 +2396,11 @@ class NodePrinter {
case Node::Kind::VariadicTuple:
return true;

case Node::Kind::ProtocolList:
if (pointer->getChild(0)->getNumChildren() <= 1)
return true;
return false;

case Node::Kind::Allocator:
case Node::Kind::ArgumentTuple:
case Node::Kind::AssociatedTypeMetadataAccessor:
Expand Down Expand Up @@ -2473,7 +2478,6 @@ class NodePrinter {
case Node::Kind::PrefixOperator:
case Node::Kind::ProtocolConformance:
case Node::Kind::ProtocolDescriptor:
case Node::Kind::ProtocolList:
case Node::Kind::ProtocolWitness:
case Node::Kind::ProtocolWitnessTable:
case Node::Kind::ProtocolWitnessTableAccessor:
Expand Down Expand Up @@ -2686,8 +2690,6 @@ class NodePrinter {
} // end anonymous namespace

static bool isExistentialType(NodePointer node) {
assert(node->getKind() == Node::Kind::Type);
node = node->getChild(0);
return (node->getKind() == Node::Kind::ExistentialMetatype ||
node->getKind() == Node::Kind::ProtocolList);
}
Expand Down Expand Up @@ -3004,7 +3006,10 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType)
if (!pointer->hasChildren())
need_parens = true;
else {
Node::Kind child0_kind = pointer->getChild(0)->getChild(0)->getKind();
Node::Kind child0_kind = pointer->getChild(0)->getKind();
if (child0_kind == Node::Kind::Type)
child0_kind = pointer->getChild(0)->getChild(0)->getKind();

if (child0_kind != Node::Kind::VariadicTuple &&
child0_kind != Node::Kind::NonVariadicTuple)
need_parens = true;
Expand Down Expand Up @@ -3410,8 +3415,13 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType)
Printer << " ";
Idx++;
}
NodePointer type = pointer->getChild(Idx);
NodePointer type = pointer->getChild(Idx)->getChild(0);
bool needs_parens = !isSimpleType(type);
if (needs_parens)
Printer << "(";
print(type);
if (needs_parens)
Printer << ")";
if (isExistentialType(type)) {
Printer << ".Protocol";
} else {
Expand Down
3 changes: 0 additions & 3 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -804,9 +804,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.EnableExperimentalPropertyBehaviors |=
Args.hasArg(OPT_enable_experimental_property_behaviors);

Opts.EnableExperimentalNestedGenericTypes |=
Args.hasArg(OPT_enable_experimental_nested_generic_types);

Opts.EnableClassResilience |=
Args.hasArg(OPT_enable_class_resilience);

Expand Down
27 changes: 0 additions & 27 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3969,33 +3969,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
return true;
}

if (!TC.Context.LangOpts.EnableExperimentalNestedGenericTypes) {
if (auto parent = dyn_cast<NominalTypeDecl>(DC)) {
if (NTD->getGenericParams())
TC.diagnose(NTD->getLoc(), diag::unsupported_generic_nested_in_type,
NTD->getName(),
parent->getName());
else
TC.diagnose(NTD->getLoc(),
diag::unsupported_type_nested_in_generic_type,
NTD->getName(),
parent->getName());
NTD->setInvalid();
return true;
} else if (auto ED = dyn_cast<ExtensionDecl>(DC)) {
auto *parent = ED->getAsNominalTypeOrNominalTypeExtensionContext();
if (parent == nullptr) {
/* Invalid extension -- diagnosed elsewhere */
return true;
}

TC.diagnose(NTD->getLoc(),
diag::unsupported_type_nested_in_generic_extension,
NTD->getName(),
parent->getName());
}
}

if (DC->isLocalContext() && DC->isGenericContext()) {
// A local generic context is a generic function.
if (auto AFD = dyn_cast<AbstractFunctionDecl>(DC)) {
Expand Down
33 changes: 14 additions & 19 deletions stdlib/public/core/HashedCollections.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,6 @@ public struct Set<Element : Hashable> :
internal typealias _VariantBuffer = _VariantSetBuffer<Element>
internal typealias _NativeBuffer = _NativeSetBuffer<Element>

/// The index type for subscripting the set.
public typealias Index = SetIndex<Element>

internal var _variantBuffer: _VariantBuffer

/// Creates a new, empty set with at least the specified number of elements'
Expand Down Expand Up @@ -1642,9 +1639,6 @@ public struct Dictionary<Key : Hashable, Value> :
/// key-value pair.
public typealias Element = (key: Key, value: Value)

/// The index type of a dictionary.
public typealias Index = DictionaryIndex<Key, Value>

internal var _variantBuffer: _VariantBuffer

/// Creates an empty dictionary.
Expand Down Expand Up @@ -4705,6 +4699,7 @@ internal enum ${Self}IndexRepresentation<${TypeParametersDecl}> {
case _cocoa(_CocoaIndex)
}

extension ${Self} {
%{
if Self == 'Set':
SubscriptingWithIndexDoc = """\
Expand All @@ -4726,12 +4721,7 @@ elif Self == 'Dictionary':
}%

${SubscriptingWithIndexDoc}
public struct ${Self}Index<${TypeParametersDecl}> :
Comparable {
// FIXME(ABI)#34 (Nesting types in generics): `DictionaryIndex` and `SetIndex` should
// be nested types (Dictionary.Index and Set.Index).
// rdar://problem/17002096

public struct Index : Comparable {
// Index for native buffer is efficient. Index for bridged NS${Self} is
// not, because neither NSEnumerator nor fast enumeration support moving
// backwards. Even if they did, there is another issue: NSEnumerator does
Expand All @@ -4750,12 +4740,12 @@ public struct ${Self}Index<${TypeParametersDecl}> :
internal var _value: ${Self}IndexRepresentation<${TypeParameters}>

@_versioned
internal static func _native(_ index: _NativeIndex) -> ${Self}Index {
internal static func _native(_ index: _NativeIndex) -> Index {
return ${Self}Index(_value: ._native(index))
}
#if _runtime(_ObjC)
@_versioned
internal static func _cocoa(_ index: _CocoaIndex) -> ${Self}Index {
internal static func _cocoa(_ index: _CocoaIndex) -> Index {
return ${Self}Index(_value: ._cocoa(index))
}
#endif
Expand Down Expand Up @@ -4789,10 +4779,15 @@ public struct ${Self}Index<${TypeParametersDecl}> :
#endif
}

extension ${Self}Index {
}

public typealias ${Self}Index<${TypeParametersDecl}> =
${Self}<${TypeParameters}>.Index

extension ${Self}.Index {
public static func == (
lhs: ${Self}Index<${TypeParameters}>,
rhs: ${Self}Index<${TypeParameters}>
lhs: ${Self}<${TypeParameters}>.Index,
rhs: ${Self}<${TypeParameters}>.Index
) -> Bool {
if _fastPath(lhs._guaranteedNative) {
return lhs._nativeIndex == rhs._nativeIndex
Expand All @@ -4813,8 +4808,8 @@ extension ${Self}Index {
}

public static func < (
lhs: ${Self}Index<${TypeParameters}>,
rhs: ${Self}Index<${TypeParameters}>
lhs: ${Self}<${TypeParameters}>.Index,
rhs: ${Self}<${TypeParameters}>.Index
) -> Bool {
if _fastPath(lhs._guaranteedNative) {
return lhs._nativeIndex < rhs._nativeIndex
Expand Down
Loading