Skip to content

Commit b8c70b0

Browse files
committed
Auto merge of #45918 - chrisvittal:impl-trait-pr, r=nikomatsakis
Implement `impl Trait` in argument position (RFC1951, Universal quantification) Implements the remainder of #44721, part of #34511. **Note**: This PR currently allows argument position `impl Trait` in trait functions. The machinery is there to prevent this if we want to, but it currently does not. Rename `hir::TyImplTrait` to `hir::TyImplTraitExistential` and add `hir::TyImplTraitUniversal(DefId, TyParamBounds)`. The `DefId` is needed to extract the index of the parameter in `ast_ty_to_ty`. Introduce an `ImplTraitContext` enum to lowering to keep track of the kind and allowedness of `impl Trait` in that position. This new argument is passed through many places, all ending up in `lower_ty`. Modify `generics_of` and `explicit_predicates_of` to collect the `impl Trait` args into anonymous synthetic generic parameters and to extend the predicates with the appropriate bounds. Add a comparison of the 'syntheticness' of type parameters, that is, prevent the following. ```rust trait Foo { fn foo(&self, &impl Debug); } impl Foo for Bar { fn foo<U: Debug>(&self, x: &U) { ... } } ``` And vice versa. Incedentally, supress `unused type parameter` errors if the type being compared is already a `TyError`. **TODO**: I have tried to annotate open questions with **FIXME**s. The most notable ones that haven't been resolved are the names of the `impl Trait` types and the questions surrounding the new `compare_synthetic_generics` method. 1. For now, the names used for `impl Trait` parameters are `keywords::Invalid.name()`. I would like them to be `impl ...` if possible, but I haven't figured out a way to do that yet. 2. For `compare_synthetic_generics` I have tried to outline the open questions in the [function itself](https://github.com/chrisvittal/rust/blob/3fc9e3705f7bd01f3cb0ea470cf2892f17a92350/src/librustc_typeck/check/compare_method.rs#L714-L725) r? @nikomatsakis
2 parents fa26421 + 4ce61b7 commit b8c70b0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1146
-325
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# `universal_impl_trait`
2+
3+
The tracking issue for this feature is: [#34511].
4+
5+
[#34511]: https://github.com/rust-lang/rust/issues/34511
6+
7+
--------------------
8+
9+
The `universal_impl_trait` feature extends the [`conservative_impl_trait`]
10+
feature allowing the `impl Trait` syntax in arguments (universal
11+
quantification).
12+
13+
[`conservative_impl_trait`]: ./language-features/conservative-impl-trait.html
14+
15+
## Examples
16+
17+
```rust
18+
#![feature(universal_impl_trait)]
19+
use std::ops::Not;
20+
21+
fn any_zero(values: impl IntoIterator<Item = i32>) -> bool {
22+
for val in values { if val == 0 { return true; } }
23+
false
24+
}
25+
26+
fn main() {
27+
let test1 = -5..;
28+
let test2 = vec![1, 8, 42, -87, 60];
29+
assert!(any_zero(test1));
30+
assert!(bool::not(any_zero(test2)));
31+
}
32+
```

src/librustc/diagnostics.rs

+40
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,46 @@ If you want to get command-line arguments, use `std::env::args`. To exit with a
17701770
specified exit code, use `std::process::exit`.
17711771
"##,
17721772

1773+
E0562: r##"
1774+
Abstract return types (written `impl Trait` for some trait `Trait`) are only
1775+
allowed as function return types.
1776+
1777+
Erroneous code example:
1778+
1779+
```compile_fail,E0562
1780+
#![feature(conservative_impl_trait)]
1781+
1782+
fn main() {
1783+
let count_to_ten: impl Iterator<Item=usize> = 0..10;
1784+
// error: `impl Trait` not allowed outside of function and inherent method
1785+
// return types
1786+
for i in count_to_ten {
1787+
println!("{}", i);
1788+
}
1789+
}
1790+
```
1791+
1792+
Make sure `impl Trait` only appears in return-type position.
1793+
1794+
```
1795+
#![feature(conservative_impl_trait)]
1796+
1797+
fn count_to_n(n: usize) -> impl Iterator<Item=usize> {
1798+
0..n
1799+
}
1800+
1801+
fn main() {
1802+
for i in count_to_n(10) { // ok!
1803+
println!("{}", i);
1804+
}
1805+
}
1806+
```
1807+
1808+
See [RFC 1522] for more details.
1809+
1810+
[RFC 1522]: https://github.com/rust-lang/rfcs/blob/master/text/1522-conservative-impl-trait.md
1811+
"##,
1812+
17731813
E0591: r##"
17741814
Per [RFC 401][rfc401], if you have a function declaration `foo`:
17751815

src/librustc/hir/intravisit.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
591591
}
592592
visitor.visit_lifetime(lifetime);
593593
}
594-
TyImplTrait(ref bounds) => {
594+
TyImplTraitExistential(ref bounds) => {
595+
walk_list!(visitor, visit_ty_param_bound, bounds);
596+
}
597+
TyImplTraitUniversal(_, ref bounds) => {
595598
walk_list!(visitor, visit_ty_param_bound, bounds);
596599
}
597600
TyTypeof(expression) => {

0 commit comments

Comments
 (0)