DST coercions fall over with UFCS

e4e0e5d
Opened by Aria Desires at 2023-12-10 10:34:42
#![feature(core, rc_weak)]

use std::cell::RefCell;
use std::rc::{Rc, Weak};

trait Baz { fn get(&self) -> i32; }
impl Baz for i32 { fn get(&self) -> i32 { *self } }

fn main() {
    let a: Rc<RefCell<i32>> = Rc::new(RefCell::new(42));
    let c1: Weak<RefCell<Baz>> = Rc::downgrade(&a);             // Doesn't work
    let c2: Weak<RefCell<Baz>> = Rc::downgrade(&a) as Weak<_>;  // works
    let c3: Weak<RefCell<Baz>> = a.downgrade();                 // works
}

CC @nrc

  1. This is difficult: the "expected type" propagation is too eager here. It should be just a hint, only with the instantiated generic signature being enforced. Might be a bit hard to handle, but a different variant of Expectation that doesn't error on type mismatches, could work. The argument handling does coercion, and could also ignore a type mismatch with the hint there, as long as the orignal formal super-type is unified with the expression's type. Then a coercion would be enabled on the return type.

    Eduard-Mihai Burtescu at 2015-08-17 23:21:16

  2. Triage: no real change. The flags can be removed, c3 doesn't work because downgrade is no longer a method, c1 still fails.

    Steve Klabnik at 2017-02-07 20:27:12

  3. Triage: here's the full code, today:

    use std::cell::RefCell;
    use std::rc::{Rc, Weak};
    
    trait Baz { fn get(&self) -> i32; }
    impl Baz for i32 { fn get(&self) -> i32 { *self } }
    
    fn main() {
        let a: Rc<RefCell<i32>> = Rc::new(RefCell::new(42));
        let c1: Weak<RefCell<dyn Baz>> = Rc::downgrade(&a);             // Doesn't work
        let c2: Weak<RefCell<dyn Baz>> = Rc::downgrade(&a) as Weak<_>;  // works
    }
    

    and the error:

    error[E0308]: mismatched types
     --> src/main.rs:9:52
      |
    9 |     let c1: Weak<RefCell<dyn Baz>> = Rc::downgrade(&a);             // Doesn't work
      |                                                    ^^ expected trait Baz, found i32
      |
      = note: expected type `&std::rc::Rc<std::cell::RefCell<dyn Baz>>`
                 found type `&std::rc::Rc<std::cell::RefCell<i32>>`
    

    Steve Klabnik at 2019-12-25 16:00:36