owned this note
owned this note
Published
Linked with GitHub
# 2024-07-09 high bandwidth
## Search graph woes
https://hackmd.io/hcl2qyr_T_qWb6hWd_NUxg
## Leak check
FCP for disabling candidate in candidate selection
- https://github.com/rust-lang/rust/pull/119820
- intended, but *undesirable* breakage https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=07336ca0df065c7767e4afbb322f74c7
proposal:
* add `||` constraints to region constraints
* instantiate the higher-ranked goal
* evaluate each candidate against that
weird example:
* Goal is `for<'a> T: Trait<'a, ?U>`
* Candidates are
* where-clause: `T: Trait<'static, i32>`
* impl `for<'a, V> T: Trait<'a, V>`
* Different substitutions, so what happens?
* On stable:
* we detect the higher-ranked error and ignore the where-clause (but would otherwise have constrained `?U = i32`)
original example:
* Goal is `for<'a> T: Trait<'a>`
* Candidates
* where-clause: `T: Trait<'static>`
* impl `for<'a> T: Trait<'a> where WC`
* Evaluate the candidates you get
* `'a = 'static`
* #t
* Result?
* Substitution
* Region constraint `'a = 'static || #t`
Deferred: implications
Conclusion:
* revert the PR
* try implementing guidance etc in the new solver
* niko: "worth a try"
* lcnr, with a notable lack of enthusiasm: "sure."
## Oli ATPIT
opaque types: *mostly* the same as inference variables, but only *mostly*
For candidate selection they are treated as rigid types, which involves one special case
Trying to match if an opaque type implements a trait, also go through all the where-bounds, if a where-bound *happens* to have something that matches, we'll constrain the opaque type. Happens way too early.
e.g. `impl Trait: Default` in `fn foo<T: Default>()`. WIP PR: https://github.com/rust-lang/rust/pull/127034
https://github.com/rust-lang/rust/pull/127034
```rust
fn filter_fold<T, Acc>(
mut predicate: impl FnMut(&T) -> bool,
mut fold: impl FnMut(Acc, T) -> Acc,
) -> impl FnMut(Acc, T) -> Acc {
move |acc, item| if predicate(&item) { fold(acc, item) } else { acc }
}
```
```rust
trait Trait {}
impl<T> Trait for T {}
fn foo<T: Trait>() -> impl Trait {
1u8
}
```
behavior with only `DefineOpaqueTypes::Yes`
- `impl Trait: Trait`
- if self type is an inference variable, bail with ambiguity ~> continue
- go through `where`-bounds, see a `T: Trait` candidate
- apply this candidate and constrain `impl Trait` with `T`
@lcnr assumption: replace opaque self types with hidden type:
- `impl Trait: Trait`
- replace `impl Trait` with its hidden type: `?hidden: Trait`
- if self type is an inference variable, bail with ambiguity ~> bail
just skip if opaque type is definable
```rust
pub(crate) struct NeverShortCircuit<T>(pub T);
impl<T> NeverShortCircuit<T> {
pub fn wrap_mut_1<A, F: FnMut(A) -> T>(
mut f: F
) -> impl FnMut(A) -> NeverShortCircuit<T> {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for opaque type `impl FnMut(A) -> NeverShortCircuit<T>`
move |a| NeverShortCircuit(f(a))
}
}
```
failing in collect_unused_stmts_for_coerce_return_ty
- https://github.com/oli-obk/rust/pull/new/infer