diff --git a/src/paths.md b/src/paths.md index 7f8ca41665..3e364dd581 100644 --- a/src/paths.md +++ b/src/paths.md @@ -83,7 +83,10 @@ Vec::::with_capacity(1024); ``` r[paths.expr.argument-order] -The order of generic arguments is restricted to lifetime arguments, then type arguments, then const arguments, then equality constraints. +The order of generic arguments is restricted to lifetime arguments, then type arguments, then const arguments, then [equality constraints][bound.equality]. + +r[paths.expr.generic-bindings] +[GenericArgsBinding]s are currently only allowed for [equality constraints][bound.equality]. r[paths.expr.complex-const-params] Const arguments must be surrounded by braces unless they are a [literal], an [inferred const], or a single segment path. An [inferred const] may not be surrounded by braces. diff --git a/src/trait-bounds.md b/src/trait-bounds.md index 3493e8ac21..c8be6e7b20 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -100,6 +100,63 @@ r[bound.sized] `?` is only used to relax the implicit [`Sized`] trait bound for [type parameters] or [associated types]. `?Sized` may not be used as a bound for other types. +r[bound.equality] +## Equality constraints +A trait bound that includes a [GenericArgsBinding] expresses an equality constraint on an associated type of a trait. + +```rust +trait Tr { type Output; } +struct S {} +impl Tr for S { type Output = S; } +fn foo>() {} +``` + +Equality constraints cannot currently be expressed using a [WhereClause]. + +```rust,compile_fail +# trait Tr { type Output; } +# struct S {} +# impl Tr for S { type Output = S; } +// error: equality constraints are not yet supported in `where` clauses +fn uses_where() where T::Output = S {} +``` + +Equality constraints must come after any input types (type parameters of a trait) in [GenericArgs]. + +```rust,compile_fail +trait Tr { type Output; fn foo(x: T); } +struct S {} +impl Tr for S { type Output = S; fn foo(x: T) {} } +// error: generic arguments must come before the first constraint +fn wrong_order>() {} +``` + +Equality constraints cannot be used in a [QualifiedPathType]. + +```rust,compile_fail,E0229 +# trait Tr { type Output; fn foo(x: T); } +# struct S {} +# impl Tr for S { type Output = S; fn foo(x: T) {} } +// error[E0229]: associated item constraints are not allowed here +fn uses_qualified_path() { >::foo(()); } +``` + +r[bound.equality.trait-object] +Equality constraints are *required* for generic [trait objects]. + +```rust,compile_fail,E0191 +trait Foo { + type Output1; + type Output2; +} +// correct: not a trait object +fn uses_foo>(x: T) {} +// error[E0191]: the value of the associated types `Output1` and `Output2` in `Foo` must be specified +fn uses_foo_obj(x: Box>) {} +// correct: all associated types constrained +fn also_foo_obj(x: Box>) {} +``` + r[bound.lifetime] ## Lifetime bounds