Skip to content

Commit 2c61468

Browse files
committed
Change scoping rules per weekly meeting. Clarify super traits
1 parent 2c6936b commit 2c61468

File tree

1 file changed

+57
-43
lines changed

1 file changed

+57
-43
lines changed

active/0000-associated-items.md

Lines changed: 57 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ fn trait_empty<C: Container>() -> C;
600600

601601
#### Via a `TYPE_SEGMENT` prefix
602602

603-
> The following text is unchanged from the
603+
> The following text is *slightly changed* from the
604604
> [UFCS RFC](https://github.com/rust-lang/rfcs/pull/132).
605605
606606
When a path begins with a `TYPE_SEGMENT`, it is a type-relative path. If this is
@@ -628,18 +628,6 @@ Given a path `<T>::m::...`:
628628
- Otherwise, rewrite the path to `<T as Trait>::m::...` and
629629
continue.
630630

631-
#### Via the `Self` or associated types as a prefix
632-
633-
In the context of trait body, the type `Self`, or associated type names, may
634-
appear as a prefix.
635-
636-
For a trait `Trait`:
637-
638-
* A reference `T` where `T` is an associated type defined in `Trait` is rewritten
639-
`<Self as Trait>::T`.
640-
641-
* A reference `Self::ID` is rewritten `<Self as Trait>::ID`.
642-
643631
#### Via a `IMPL_SEGMENT` prefix
644632

645633
> The following text is *somewhat different* from the
@@ -742,7 +730,7 @@ function knows nothing about the associated type `G::N`. However, a *client* of
742730
`pick_node` that instantiates it with a particular concrete graph type will also
743731
know the concrete type of the value returned from the function -- here, `MyNode`.
744732

745-
## Scoping of associated items
733+
## Scoping of `trait` and `impl` items
746734

747735
Associated types are frequently referred to in the signatures of a trait's
748736
methods and associated functions, and it is natural and convneient to refer to
@@ -770,19 +758,50 @@ trait Graph {
770758
}
771759
```
772760

773-
The proposed scoping rule is:
761+
This RFC proposes to treat both `trait` and `impl` bodies (both
762+
inherent and for traits) the same way we treat `mod` bodies: *all*
763+
items being defined are in scope. In particular, methods are in scope
764+
as UFCS-style functions:
774765

775-
* Associated types are in scope for the trait body
776-
* Associated lifetimes are in scope for the trait body
777-
* All other items must be referenced through `Self`
766+
```rust
767+
trait Foo {
768+
type AssocType;
769+
lifetime 'assoc_lifetime;
770+
static ASSOC_STATIC: uint;
771+
fn assoc_fn() -> Self;
772+
773+
// Note: 'assoc_lifetime and AssocType in scope:
774+
fn method(&self, Self) -> &'assoc_lifetime AssocType;
775+
776+
fn default_method(&self) -> uint {
777+
// method in scope UFCS-style, assoc_fn in scope
778+
let _ = method(self, assoc_fn());
779+
ASSOC_STATIC // in scope
780+
}
781+
}
778782

779-
These rules roughly match our convention of importing type names at the top
780-
level, but not function names. They leaves intact today's restriction that
781-
associated functions are not directly in scope for default methods. Some
782-
alternatives are discussed at the end of the RFC.
783+
// Same scoping rules for impls, including inherent impls:
784+
struct Bar;
785+
impl Bar {
786+
fn foo(&self) { ... }
787+
fn bar(&self) {
788+
foo(self); // foo in scope UFCS-style
789+
...
790+
}
791+
}
792+
```
793+
794+
Items from super traits are *not* in scope, however. See
795+
[the discussion on super traits below](#super-traits) for more detail.
796+
797+
These scope rules provide good ergonomics for associated types in
798+
particular, and a consistent scope model for language constructs that
799+
can contain items (like traits, impls, and modules). In the long run,
800+
we should also explore imports for trait items, i.e. `use
801+
Trait::some_method`, but that is out of scope for this RFC.
783802

784803
Note that, according to this proposal, associated types/lifetimes are *not* in
785-
scope for the optional where clause on the trait header. For example:
804+
scope for the optional `where` clause on the trait header. For example:
786805

787806
```rust
788807
trait Foo<Input>
@@ -1339,33 +1358,28 @@ like `Sum` above into associated types later.
13391358
This is perhaps a reasonable fallback, but it seems better to introduce a clean
13401359
design with both multidispatch and associated items together.
13411360

1342-
## Alternative scoping rules for associated items in trait bodies
1343-
1344-
The proposed scoping rules for associated items make a distinction between
1345-
types/lifetimes, which are in scope for the trait body, and other items, which
1346-
are not.
1347-
1348-
Sensible alternatives would be to take one of the extreme positions:
1361+
# Unresolved questions
13491362

1350-
* *No* associated items are in scope for the trait body; everything must be
1351-
referenced through `Self`.
1363+
## Super traits
13521364

1353-
This option seems needlessly painful when using associated types.
1365+
This RFC largely ignores super traits.
13541366

1355-
* *All* associated items are in scope for the trait body.
1367+
Currently, the implementation of super traits treats them identically to a
1368+
`where` clause that bounds `Self`, and this RFC does not propose to change
1369+
that. However, a follow-up RFC should clarify that this is the intended
1370+
semantics for super traits.
13561371

1357-
This option is a reasonable alternative to the proposed rules, and makes it
1358-
somewhat nicer to write default methods, since statics and associated
1359-
functions are automatically in scope.
1372+
Note that this treatment of super traits is, in particular, consistent with the
1373+
proposed scoping rules, which do not bring items from super traits into scope in
1374+
the body of a subtrait; they must be accessed via `Self::item_name`.
13601375

1361-
* *All* trait items (including methods, understood as UFCS functions) are in
1362-
scope for the trait body.
1376+
## Equality constraints in `where` clauses
13631377

1364-
This option seems overly aggressive: there is little benefit to writing
1365-
`some_method(self, arg)` rather than `self.some_method(arg)`, and the UFCS
1366-
version loses autoderef etc.
1378+
This RFC allows equality constraints on types for associated types, but does not
1379+
propose a similar feature for `where` clauses. That will be the subject of a
1380+
follow-up RFC.
13671381

1368-
# Unresolved questions
1382+
## Multiple trait object bounds for the same trait
13691383

13701384
The design here makes it possible to write bounds or trait objects that mention
13711385
the same trait, multiple times, with different inputs:

0 commit comments

Comments
 (0)