Skip to content

Inference replaces bounded type parameter with sole implementer (was: action-at-a-distance regression) #18187

Closed

Description

@arielb1

The following code does not compile:

pub trait ScanCursor {
    fn pop_ws(&self) -> Self;
}

pub struct Cursor;

impl ScanCursor for Cursor {
    fn pop_ws(&self) -> Cursor { unreachable!() }
}

pub trait Scanner {
    fn scan<Cur: ScanCursor>(cursor: &Cur) -> Self;
}

fn main() {
    let cur : Cursor = Cursor;
    // 
    let _tmp = &cur.pop_ws(); // removing this still fails
    // let _ : Stmt = Scanner::scan(_tmp)
    let _ : Stmt = Scanner::scan(&cur.pop_ws());
}

struct Stmt;

// Moving this above main compiles
impl Scanner for Stmt {
    fn scan<Cur: ScanCursor>(cur: &Cur) -> Stmt {
        // Fails to compile
        let _s: Stmt = Scanner::scan(&cur.pop_ws());
        loop{}
   }
}

// Added 2014-10-21
#[cfg(compiles)]
impl ScanCursor for ((),(()),((),(()))) /* or whatever */ {
    fn pop_ws(&self) ->  ((),(()),((),(()))) { unreachable!() }
}

With an error in scan:

<anon>:29:38: 29:51 error: mismatched types: expected `&Cursor`, found `&Cur` (expected struct Cursor, found type parameter)
<anon>:29         let _s: Stmt = Scanner::scan(&cur.pop_ws());
                                               ^~~~~~~~~~~~~
error: aborting due to previous error

However, doing any of the 2 fixes suggested in the comments fixes this, which is strange, as the fixes don't touch the affected function.

The issue started at commit 590a61f788e058d7ae95806f55258bce3ae45567 (2014-10-13), which fixed issue #18019. The code compiles on older version of rustc.

Activity

  1. dwrensha commented on Oct 20, 2014

    @dwrensha
    Contributor

    Perhaps related to this other action-at-a-distance problem that I recently reported:
    #18163

  2. arielb1 commented on Oct 21, 2014

    @arielb1
    ContributorAuthor

    @pfalabella encountered a similar issue on IRC, with the code:

    use std::num::{One, one};
    
    #[cfg(not(test))]
    fn main() {
        let _: Hamming<int> = Hamming::new(0);
    }
    /// representation of a Hamming number, allows to abstract on how the hamming number is stored
    pub trait HammingNumber: Eq + Ord + Mul<Self, Self> + One {
        fn multipliers() -> Self;
    }
    
    #[cfg(compiles)]
    impl HammingNumber for i64 {
        // returns the multipliers 2, 3 and 5 in the representation for the HammingNumber
        fn multipliers() -> i64 {
            0
        }
    }
    
    impl HammingNumber for int {
        // returns the multipliers 2, 3 and 5 in the representation for the HammingNumber
        fn multipliers() -> int {
            0
        }
    }
    
    pub struct Hamming<T> {
        // Using a RingBuf as a queue, push to the back, pop from the front
        q2: Vec<T>,
    }
    
    impl <T: HammingNumber> Hamming<T> {
        /// Static constructor method
        /// `n` initializes the capacity of the queues
        pub fn new(n: uint) -> Hamming<T> {
            let mut h =
                Hamming{q2: Vec::with_capacity(n),};
            h.q2.push(one());
            h
        }
        /// Pushes the next multiple of `n` (x2, x3, x5) to the queues
        pub fn enqueue(&mut self, n: &T) {
            let two : T = HammingNumber::multipliers();
            self.q2.push(*n * two);
        }
    }

    Which gives the error

    <anon>:44:23: 44:51 error: mismatched types: expected `T`, found `int` (expected type parameter, found int)
    <anon>:44         let two : T = HammingNumber::multipliers();
    

    But compiles with --cfg compiles (or if you remove the cfg test).

  3. arielb1 commented on Oct 21, 2014

    @arielb1
    ContributorAuthor

    I added a similar #[cfg(compiles)] block to the original code.

    The issue seems that when a trait Tr is impl-ed only by a single type A, and you have a function generic over T: Tr, then rustc replaces some of the occurrences of T in the function's body with A.

  4. changed the title [-]Inference action-at-a-distance regression[/-] [+]Inference replaces bounded type parameter with sole implementer (was: action-at-a-distance regression)[/+] on Oct 21, 2014
  5. nrc commented on Oct 22, 2014

    @nrc
    Member

    See #18209 for a much reduced test case

  6. self-assigned this
    on Oct 22, 2014
  7. nikomatsakis commented on Oct 22, 2014

    @nikomatsakis
    Contributor

    Appears to be a dup of #18209, closing. (That is, my patch for #18209 fixes these test cases as well.)

  8. added a commit that references this issue on Oct 8, 2024
    00399ab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions