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

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

Merged
merged 8 commits into from Nov 18, 2016
View
@@ -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 {}

This comment has been minimized.

@jrose-apple

jrose-apple Nov 18, 2016

Member

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

@jrose-apple

jrose-apple Nov 18, 2016

Member

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

This comment has been minimized.

@slavapestov
@slavapestov

slavapestov Nov 18, 2016

Member

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:
@@ -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))
@@ -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.
@@ -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">;
View
@@ -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:
@@ -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:
@@ -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);
}
@@ -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;
@@ -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 {
@@ -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);
View
@@ -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)) {
@@ -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'
@@ -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.
@@ -4705,6 +4699,7 @@ internal enum ${Self}IndexRepresentation<${TypeParametersDecl}> {
case _cocoa(_CocoaIndex)
}
extension ${Self} {
%{
if Self == 'Set':
SubscriptingWithIndexDoc = """\
@@ -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
@@ -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
@@ -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
@@ -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
Oops, something went wrong.
ProTip! Use n and p to navigate between commits in a pull request.