Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICE in subst #7332

Closed
emberian opened this issue Jun 23, 2013 · 4 comments
Closed

ICE in subst #7332

emberian opened this issue Jun 23, 2013 · 4 comments

Comments

@emberian
Copy link
Member

Yet another one I couldn't reduce, this one started happening after I added the prefill<U> method.

Might be something with default methods? (@sully?)

// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
// // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::hashmap::HashMap;

#[allow(default_methods)]

/**
 * An "interner" is a data structure that associates values with uint tags, allowing bidirectional
 * lookup (ie, given a value, get the tag, or given a tag, get the value). This allows for efficient
 * storage and comparison of large values that would be expensive to copy around or compare
 */
// FIXME #7312: inherit `Default` when it exists
// FIXME #6997: just use Iterator, not IteratorUtil
pub trait Interner<T> {
    pub fn new() -> Self;
    /// Create a new interner and intern all the values in `init`
    pub fn prefill<U: IteratorUtil<T>>(init: U) -> Self {
        let in: Self = Interner::new();
        for init.advance |v| {
            in.intern(v);
        }
        in
    }
    /// Intern a value, returning the tag used to refer to it
    pub fn intern(&self, val: T) -> uint;
    /// Get the value corresponding to a tag
    pub fn get<'a>(&'a self, tag: uint) -> Option<&'a T>;
    /// Get the tag corresponding to a value equivalent to `Q`
    pub fn find_equiv<Q: Hash + IterBytes + Equiv<T>>(&self, val: &Q) -> Option<uint>;
}

/**
 * A simple implementation of an interner, using a std::hashmap::HashMap for associating a value to a
 * tag and storing values in a vector.
 */
pub struct SimpleInterner<T> {
    priv map: HashMap<T, uint>,
    priv vect: ~[T]
}

impl<T: Hash + IterBytes + Eq> Interner<T> for SimpleInterner<T> {
    pub fn new() -> SimpleInterner<T> {
        SimpleInterner {
            map: HashMap::new(),
            vect: ~[]
        }
    }
    pub fn prefill<U: IteratorUtil<T>>(init: U) -> SimpleInterner<T> {
        let hm = HashMap::new();
        let (lower, _) = init.size_hint();
        hm.reserve_at_least(lower.get_or_zero());
        let mut vect = std::vec::with_capacity(init.len());
        let mut i = 0;
        for init.advance |&v| {
            if hm.find_or_insert(v, i) == i {
                unsafe {
                    std::vec::raw::init_elem(vect, i, v);
                }
                i += 1;
            }
        }
        SimpleInterner {map: hm, vect: vect}
    }
    pub fn intern(&self, val: T) -> uint {
        let i = self.vect.len();
        let x = self.map.find_or_insert(val, i);
        if x == i {
            self.vec.push(val);
        }
        x
    }
    pub fn get<'a>(&'a self, tag: uint) -> Option<&'a T> {
        if tag > self.vect.len() {
            None
        } else {
            Some(&self.vect[tag])
        }
    }
    pub fn find_equiv<Q: Hash + IterBytes + Equiv<T>>(&self, val: &Q) -> Option<uint> {
        self.map.find_equiv(val)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    #[should_fail]
    fn i1 () {
        let i: SimpleInterner<~str> = Interner::new();
        i.get(13);
    }
}
@emberian
Copy link
Member Author

Sorry for not pasting the error I got:

rust: task failed at 'index out of bounds: the len is 0 but the index is 0', /home/cmr/hacking/rust/src/librustc/middle/subst.rs:58

@alexcrichton
Copy link
Member

@msullivan, sully is someone else :(

@emberian
Copy link
Member Author

oh whoops :(

@huonw
Copy link
Member

huonw commented Jul 14, 2013

The code above seems to work (after fixing various type errors), and this appears to be the same issue as #7295, which is fixed.

@huonw huonw closed this as completed Jul 14, 2013
flip1995 pushed a commit to flip1995/rust that referenced this issue Jun 17, 2021
…fate

redundant_clone: fix comment

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants