2024-07-09 high bandwidth

Search graph woes

https://hackmd.io/hcl2qyr_T_qWb6hWd_NUxg

Leak check

FCP for disabling candidate in candidate selection

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

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 } 
 } 
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

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

Select a repo