diff --git a/standard/classes.md b/standard/classes.md index ba26b5c0d..fd0de7de7 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -63,6 +63,7 @@ class_modifier | 'abstract' | 'sealed' | 'static' + | 'file' | unsafe_modifier // unsafe code support ; ``` @@ -75,10 +76,22 @@ The `new` modifier is permitted on nested classes. It specifies that the class h The `public`, `protected`, `internal`, and `private` modifiers control the accessibility of the class. Depending on the context in which the class declaration occurs, some of these modifiers might not be permitted ([§7.5.2](basic-concepts.md#752-declared-accessibility)). +It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + When a partial type declaration ([§15.2.7](classes.md#1527-partial-type-declarations)) includes an accessibility specification (via the `public`, `protected`, `internal`, and `private` modifiers), that specification shall agree with all other parts that include an accessibility specification. If no part of a partial type includes an accessibility specification, the type is given the appropriate default accessibility ([§7.5.2](basic-concepts.md#752-declared-accessibility)). The `abstract`, `sealed`, and `static` modifiers are discussed in the following subclauses. +The `file` modifier specifies that the type being declared is local to its parent compilation unit. A compilation unit containing a `file`-modified type shall not also contain a type declaration having the same name but without the `file` modifier. (`file` is a contextual keyword (§6.4.4) that has special meaning when used as a top-level type modifier.) + +The `file` modifier shall only appear in a type declaration for a top-level type. + +When a type declaration contains the `file` modifier, that type is said to be a ***file-local type***. + +The implementation shall guarantee that two type declarations are distinct at runtime when either both are file-local types with the same name declared in different compilation units, or one is a file-local type and the other is a non-file-local type with the same name. + +A file-local class that is an attribute type may be used as an attribute within both file-local types and non-file-local types, just as if the attribute type were a non-file-local class. + #### 15.2.2.2 Abstract classes The `abstract` modifier is used to indicate that a class is incomplete and that it is intended to be used only as a base class. An ***abstract class*** differs from a ***non-abstract class*** in the following ways: @@ -265,6 +278,8 @@ The direct base class of a class type shall be at least as accessible as the cla The direct base class of a class type shall not be any of the following types: `System.Array`, `System.Delegate`, `System.Enum`, `System.ValueType` or the `dynamic` type. Furthermore, a generic class declaration shall not use `System.Attribute` as a direct or indirect base class ([§23.2.1](attributes.md#2321-general)). +A file-local class shall not be used as a base type of a non-file-local class. + In determining the meaning of the direct base class specification `A` of a class `B`, the direct base class of `B` is temporarily assumed to be `object`, which ensures that the meaning of a base class specification cannot recursively depend on itself. Given this definition, the complete set of types upon which a class depends is the transitive closure of the *directly depends on* relationship. > *Example*: The following @@ -796,6 +811,8 @@ The modifier `partial` is used when defining a class, struct, or interface type Each part of a ***partial type*** declaration shall include a `partial` modifier and shall be declared in the same namespace or containing type as the other parts. The `partial` modifier indicates that additional parts of the type declaration might exist elsewhere, but the existence of such additional parts is not a requirement; it is valid for the only declaration of a type to include the `partial` modifier. It is valid for only one declaration of a partial type to include the base class or implemented interfaces. However, all declarations of a base class or implemented interfaces shall match, including the nullability of any specified type arguments. +For a partial type, either all parts shall include the `file` modifier and be declared in the same compilation unit, or no part shall include the `file` modifier. + All parts of a partial type shall be compiled together such that the parts can be merged at compile-time. Partial types specifically do not allow already compiled types to be extended. Nested types may be declared in multiple parts by using the `partial` modifier. Typically, the containing type is declared using `partial` as well, and each part of the nested type is declared in a different part of the containing type. @@ -874,6 +891,8 @@ class_member_declaration ; ``` +The signature of a member in a non-file-local type shall not contain a file-local type. + The members of a class are divided into the following categories: - Constants, which represent constant values associated with the class ([§15.4](classes.md#154-constants)). diff --git a/standard/delegates.md b/standard/delegates.md index 60bd30c17..d797ab9f9 100644 --- a/standard/delegates.md +++ b/standard/delegates.md @@ -29,6 +29,7 @@ delegate_modifier | 'protected' | 'internal' | 'private' + | 'file' | unsafe_modifier // unsafe code support ; ``` @@ -41,7 +42,9 @@ A delegate declaration that supplies a *variant_type_parameter_list* is a generi The `new` modifier is only permitted on delegates declared within another type, in which case it specifies that such a delegate hides an inherited member by the same name, as described in [§15.3.5](classes.md#1535-the-new-modifier). -The `public`, `protected`, `internal`, and `private` modifiers control the accessibility of the delegate type. Depending on the context in which the delegate declaration occurs, some of these modifiers might not be permitted ([§7.5.2](basic-concepts.md#752-declared-accessibility)). +The `public`, `protected`, `internal`, and `private` modifiers control the accessibility of the delegate type. Depending on the context in which the delegate declaration occurs, some of these modifiers might not be permitted ([§7.5.2](basic-concepts.md#752-declared-accessibility)). It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + +The modifier `file` has the same meaning as that for a class declaration ([§15.2.2](classes.md#1522-class-modifiers)). The delegate’s type name is *identifier*. diff --git a/standard/enums.md b/standard/enums.md index b40cbfd72..30c1c76cb 100644 --- a/standard/enums.md +++ b/standard/enums.md @@ -87,11 +87,14 @@ enum_modifier | 'protected' | 'internal' | 'private' + | 'file' ; ``` It is a compile-time error for the same modifier to appear multiple times in an enum declaration. +It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + The modifiers of an enum declaration have the same meaning as those of a class declaration ([§15.2.2](classes.md#1522-class-modifiers)). However, the `abstract`, and `sealed`, and `static` modifiers are not permitted in an enum declaration. Enums cannot be abstract and do not permit derivation. ## 20.4 Enum members diff --git a/standard/expressions.md b/standard/expressions.md index 2066e33ff..44a0a896c 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -378,6 +378,8 @@ A member lookup of a name `N` with `K` type arguments in a type `T` is proces - If `T` is a type parameter, then the set is the union of the sets of accessible members named `N` in each of the types specified as a primary constraint or secondary constraint ([§15.2.5](classes.md#1525-type-parameter-constraints)) for `T`, along with the set of accessible members named `N` in `object`. - Otherwise, the set consists of all accessible ([§7.5](basic-concepts.md#75-member-access)) members named `N` in `T`, including inherited members and the accessible members named `N` in `object`. If `T` is a constructed type, the set of members is obtained by substituting type arguments as described in [§15.3.3](classes.md#1533-members-of-constructed-types). Members that include an `override` modifier are excluded from the set. - Next, if `K` is zero, all nested types whose declarations include type parameters are removed. If `K` is not zero, all members with a different number of type parameters are removed. When `K` is zero, methods having type parameters are not removed, since the type inference process ([§12.6.3](expressions.md#1263-type-inference)) might be able to infer the type arguments. +- Next, let *F* be the compilation unit that contains the expression where member lookup is occurring. All members that are file-local types and are not declared in *F* are removed from the set. +- Next, if the set of accessible members contains file-local types, all members that are not file-local types are removed from the set. - Next, if the member is invoked, all non-invocable members are removed from the set. - Next, members that are hidden by other members are removed from the set. For every member `S.M` in the set, where `S` is the type in which the member `M` is declared, the following rules are applied: - If `M` is a constant, field, property, event, or enumeration member, then all members declared in a base type of `S` are removed from the set. diff --git a/standard/interfaces.md b/standard/interfaces.md index 63cad4e3c..671a21591 100644 --- a/standard/interfaces.md +++ b/standard/interfaces.md @@ -40,6 +40,7 @@ interface_modifier | 'protected' | 'internal' | 'private' + | 'file' | unsafe_modifier // unsafe code support ; ``` @@ -52,6 +53,10 @@ The `new` modifier is only permitted on interfaces defined within a class. It sp The `public`, `protected`, `internal`, and `private` modifiers control the accessibility of the interface. Depending on the context in which the interface declaration occurs, only some of these modifiers might be permitted ([§7.5.2](basic-concepts.md#752-declared-accessibility)). When a partial type declaration ([§15.2.7](classes.md#1527-partial-type-declarations)) includes an accessibility specification (via the `public`, `protected`, `internal`, and `private` modifiers), the rules in [§15.2.2](classes.md#1522-class-modifiers) apply. +It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + +The modifier `file` is described in [§15.2.2](classes.md#1522-class-modifiers). + ### 19.2.3 Variant type parameter lists #### 19.2.3.1 General diff --git a/standard/lexical-structure.md b/standard/lexical-structure.md index 6b8639349..513c8184d 100644 --- a/standard/lexical-structure.md +++ b/standard/lexical-structure.md @@ -607,13 +607,13 @@ A ***contextual keyword*** is an identifier-like sequence of characters that has contextual_keyword : 'add' | 'alias' | 'and' | 'ascending' | 'async' | 'await' | 'by' | 'Cdecl' | 'descending'| 'dynamic' - | 'equals' | 'Fastcall' | 'from' | 'get' | 'global' - | 'group' | 'init' | 'into' | 'join' | 'let' - | 'managed' | 'nameof' | 'nint' | 'not' | 'notnull' - | 'nuint' | 'on' | 'or' | 'orderby' | 'partial' - | 'record' | 'remove' | 'select' | 'set' | 'Stdcall' - | 'Thiscall' | 'unmanaged' | 'value' | 'var' | 'when' - | 'where' | 'yield' + | 'equals' | 'Fastcall' | 'file' | 'from' | 'get' + | 'global' | 'group' | 'init' | 'into' | 'join' + | 'let' | 'managed' | 'nameof' | 'nint' | 'not' + | 'notnull' | 'nuint' | 'on' | 'or' | 'orderby' + | 'partial' | 'record' | 'remove' | 'select' | 'set' + | 'Stdcall' | 'Thiscall' | 'unmanaged' | 'value' | 'var' + | 'when' | 'where' | 'yield' ; ``` diff --git a/standard/namespaces.md b/standard/namespaces.md index ac879ed3f..0060f3353 100644 --- a/standard/namespaces.md +++ b/standard/namespaces.md @@ -322,6 +322,8 @@ A *global_using_static_directive* only imports members and types declared direct Ambiguities between multiple *global_using_namespace_directive*s and *global_using_static_directives* are discussed in [§14.5.3](namespaces.md#1453-global-using-namespace-directives). +It is a compile-time error to use a file-local type in a *global_using_static_directive*. + ## 14.6 Using directives ### 14.6.1 General diff --git a/standard/structs.md b/standard/structs.md index 3803084ea..96af891d5 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -69,6 +69,7 @@ struct_modifier | 'internal' | 'private' | 'readonly' + | 'file' | unsafe_modifier // unsafe code support ; ``` @@ -77,6 +78,8 @@ struct_modifier It is a compile-time error for the same modifier to appear multiple times in a struct declaration. +It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + Except for `readonly`, the modifiers of a struct declaration have the same meaning as those of a class declaration ([§15.2.2](classes.md#1522-class-modifiers)). The `readonly` modifier indicates that the *struct_declaration* declares a type whose instances are immutable.