Skip to content

Commit 09ceddc

Browse files
authored
Merge pull request #2730 from lcnr/main
candidate preference, mention RPITIT issue
2 parents 0642476 + c6fb9c7 commit 09ceddc

1 file changed

Lines changed: 64 additions & 26 deletions

File tree

src/solve/candidate-preference.md

Lines changed: 64 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -260,31 +260,6 @@ We prefer builtin trait object impls over user-written impls. This is **unsound*
260260

261261
The candidate preference behavior during normalization is implemented in [`fn assemble_and_merge_candidates`].
262262

263-
### Where-bounds shadow impls
264-
265-
Normalization of associated items does not consider impls if the corresponding trait goal has been proven via a `ParamEnv` or `AliasBound` candidate.
266-
This means that for where-bounds which do not constrain associated types, the associated types remain *rigid*.
267-
268-
This is necessary to avoid unnecessary region constraints from applying impls.
269-
```rust
270-
trait Trait<'a> {
271-
type Assoc;
272-
}
273-
impl Trait<'static> for u32 {
274-
type Assoc = u32;
275-
}
276-
277-
fn bar<'b, T: Trait<'b>>() -> T::Assoc { todo!() }
278-
fn foo<'a>()
279-
where
280-
u32: Trait<'a>,
281-
{
282-
// Normalizing the return type would use the impl, proving
283-
// the `T: Trait` where-bound would use the where-bound, resulting
284-
// in different region constraints.
285-
bar::<'_, u32>();
286-
}
287-
```
288263

289264
### We always consider `AliasBound` candidates
290265

@@ -418,10 +393,73 @@ where
418393
}
419394
```
420395

396+
### Trait where-bounds shadow impls
397+
398+
Normalization of associated items does not consider impls if the corresponding trait goal has been proven via a `ParamEnv` or `AliasBound` candidate.
399+
This means that for where-bounds which do not constrain associated types, the associated types remain *rigid*.
400+
401+
#### Using impls results in different region constraints
402+
403+
This is necessary to avoid unnecessary region constraints from applying impls.
404+
```rust
405+
trait Trait<'a> {
406+
type Assoc;
407+
}
408+
impl Trait<'static> for u32 {
409+
type Assoc = u32;
410+
}
411+
412+
fn bar<'b, T: Trait<'b>>() -> T::Assoc { todo!() }
413+
fn foo<'a>()
414+
where
415+
u32: Trait<'a>,
416+
{
417+
// Normalizing the return type would use the impl, proving
418+
// the `T: Trait` where-bound would use the where-bound, resulting
419+
// in different region constraints.
420+
bar::<'_, u32>();
421+
}
422+
```
423+
424+
#### RPITIT `type_of` cycles
425+
426+
We currently have to avoid impl candidates if there are where-bounds to avoid query cycles for RPITIT, see [#139762]. It feels desirable to me to stop relying on auto-trait leakage of during RPITIT computation to remove this issue, see [#139788].
427+
428+
```rust
429+
use std::future::Future;
430+
pub trait ReactiveFunction: Send {
431+
type Output;
432+
433+
fn invoke(self) -> Self::Output;
434+
}
435+
436+
trait AttributeValue {
437+
fn resolve(self) -> impl Future<Output = ()> + Send;
438+
}
439+
440+
impl<F, V> AttributeValue for F
441+
where
442+
F: ReactiveFunction<Output = V>,
443+
V: AttributeValue,
444+
{
445+
async fn resolve(self) {
446+
// We're awaiting `<V as AttributeValue>::{synthetic#0}` here.
447+
// Normalizing that one via the the impl we're currently in
448+
// relies on `collect_return_position_impl_trait_in_trait_tys` which
449+
// ends up relying on auto-trait leakage when checking that the
450+
// opaque return type of this function implements the `Send` item
451+
// bound of the trait definition.
452+
self.invoke().resolve().await
453+
}
454+
}
455+
```
456+
421457
[`Candidate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/assembly/struct.Candidate.html
422458
[`CandidateSource`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/enum.CandidateSource.html
423459
[`fn merge_trait_candidates`]: https://github.com/rust-lang/rust/blob/e3ee7f7aea5b45af3b42b5e4713da43876a65ac9/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs#L1342-L1424
424460
[`fn assemble_and_merge_candidates`]: https://github.com/rust-lang/rust/blob/e3ee7f7aea5b45af3b42b5e4713da43876a65ac9/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs#L920-L1003
425461
[trait-system-refactor-initiative#76]: https://github.com/rust-lang/trait-system-refactor-initiative/issues/76
426462
[#24066]: https://github.com/rust-lang/rust/issues/24066
427-
[#133044]: https://github.com/rust-lang/rust/issues/133044
463+
[#133044]: https://github.com/rust-lang/rust/issues/133044
464+
[#139762]: https://github.com/rust-lang/rust/pull/139762
465+
[#139788]: https://github.com/rust-lang/rust/issues/139788

0 commit comments

Comments
 (0)