You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Generally when referring to an item with generic parameters you must specify a list of generic arguments corresponding to the item's generic parameters. In some cases it is permitted to elide these arguments but still, implicitly, a set of arguments are provided (e.g. `Vec::default()` desugars to `Vec::<_>::default()`).
13
+
14
+
For functions this is not necessarily the case, for example if we take the function `foo` from the example above and write the following code:
15
+
```rust
16
+
fnmain() {
17
+
letf=foo::<_>;
18
+
19
+
letb=String::new();
20
+
letc=String::new();
21
+
22
+
f(&b);
23
+
drop(b);
24
+
f(&c);
25
+
}
26
+
```
27
+
28
+
This code compiles perfectly fine even though there is no single lifetime that could possibly be specified in `foo::<_>` that would allow for both
29
+
the `&b` and `&c` borrows to be used as arguments (note: the `drop(b)` line forces the `&b` borrow to be shorter than the `&c` borrow). This works because the `'a` lifetime is _late bound_.
30
+
31
+
A generic parameter being late bound means that when we write `foo::<_>` we do not actually provide an argument for that parameter, instead we wait until _calling_ the function to provide the generic argument. In the above example this means that we are doing something like `f::<'_>(&b);` and `f::<'_>(&c);` (although in practice we do not actually support turbofishing late bound parameters in this manner)
32
+
33
+
It may be helpful to think of "early bound parameter" or "late bound parameter" as meaning "early provided parameter" and "late provided parameter", i.e. we provide the argument to the parameter either early (when naming the function) or late (when calling it).
34
+
35
+
Late bound parameters on functions are tracked with a [`Binder`] when accessing the signature of the function, this can be done with the [`fn_sig`] query. For more information of binders see the [chapter on `Binder`s ][ch_binders].
Generally when referring to an item with generic parameters you must specify a list of generic arguments corresponding to the item's generic parameters. In some cases it is permitted to elide these arguments but still, implicitly, a set of arguments are provided (e.g. `Vec::default()` desugars to `Vec::<_>::default()`).
40
-
41
-
For functions this is not necessarily the case, for example if we take the function `foo` from the example above and write the following code:
42
-
```rust
43
-
fnmain() {
44
-
letf=foo::<_>;
45
-
46
-
letb=String::new();
47
-
letc=String::new();
48
-
49
-
f(&b);
50
-
drop(b);
51
-
f(&c);
52
-
}
53
-
```
54
-
55
-
This code compiles perfectly fine even though there is no single lifetime that could possibly be specified in `foo::<_>` that would allow for both
56
-
the `&b` and `&c` borrows to be used as arguments (note: the `drop(b)` line forces the `&b` borrow to be shorter than the `&c` borrow). This works because the `'a` lifetime is _late bound_.
57
-
58
-
A generic parameter being late bound means that when we write `foo::<_>` we do not actually provide an argument for that parameter, instead we wait until _calling_ the function to provide the generic argument. In the above example this means that we are doing something like `f::<'_>(&b);` and `f::<'_>(&c);` (although in practice we do not actually support turbofishing late bound parameters in this manner)
59
-
60
-
It may be helpful to think of "early bound parameter" or "late bound parameter" as meaning "early provided parameter" and "late provided parameter", i.e. we provide the argument to the parameter either early (when naming the function) or late (when calling it).
61
-
62
-
Late bound parameters on functions are tracked with a [`Binder`] when accessing the signature of the function, this can be done with the [`fn_sig`] query. For more information of binders see the [chapter on `Binder`s ][ch_binders].
Copy file name to clipboardExpand all lines: src/ty_module/early_binder.md
+4-4
Original file line number
Diff line number
Diff line change
@@ -47,10 +47,10 @@ fn bar(foo: Foo<u32, f32>) {
47
47
48
48
In the compiler the `instantiate` call for this is done in [`FieldDef::ty`] ([src][field_def_ty_src]), at some point during type checking `bar` we will wind up calling `FieldDef::ty(x, &[u32, f32])` in order to obtain the type of `foo.x`.
49
49
50
-
**Note on indices:** It is possible for the indices in `Param`to not match with what the `EarlyBinder` binds. For
51
-
example, the index could be out of bounds or it could be the index of a lifetime when we were expecting a type.
52
-
These sorts of errors would be caught earlier in the compiler when translating from a `rustc_hir::Ty` to a `ty::Ty`.
53
-
If they occur later, that is a compiler bug.
50
+
**Note on indices:** It is a bug if the index of a `Param`does not match what the `EarlyBinder` binds. For
51
+
example, if the index is out of bounds or the index index of a lifetime corresponds to a type parameter.
52
+
These sorts of errors are caught earlier in the compiler during name resolution where we disallow references
53
+
to generics parameters introduced by items that should not be nameable by the inner item.
0 commit comments