Change:
Built glfw-rs using rust 0.10-pre. When referencing this crate in another source file and building, I get error: internal compiler error: unexpected failure This message reflects a bug in the Rust compiler. We would appreciate a bug report: note: the compiler hit an unexpected failure path. this is a bug Ok(task 'rustc' failed at 'assertion failed: ()', ) This is on OSX 10.9: rustc 0.10-pre ( 2014-02-18 10:16:48 -0800) host: x8664-apple-darwin
This means that you've got two versions of the same lying around, and doesn't like having two versions. This will be fixed by , I just need to land it :(
I have just build the library for the first time, and I can only find one dylib for it on my system (next to the rlib, but I gues that shouldn't cause any problems). Is there another possibility for this error? Gesendet: Mittwoch, 19. Februar 2014 um 01:09 UhrVon: "Alex Crichton" : mozilla/rust hhildebr : Re: [rust] Compiler error when referencing crate "glfw-rs" () This means that you've got two versions of the same libglfw- lying around, and rustc doesn't like having two versions. This will be fixed by , I just need to land it :( — Reply to this email directly or view it on GitHub.
my reading of is that having a dylib and an rlib simultaneously is a problem.
Having a dylib and an rlib simultaneously should not be a problem, it is in fact quite common. Having 2 dylibs and 1 rlib or 2 rlibs and 1 dylib however is a problem.
sorry, my mistake in parsing the title of .
Yes, indeed, I had several identical dylibs, but it wasn't the glfw-rs.. there were rust libs in /usr/local/lib and /usr/local/lib/rustlib/... Thanks! Gesendet: Mittwoch, 19. Februar 2014 um 17:15 UhrVon: "Alex Crichton" : mozilla/rust hhildebr : Re: [rust] Compiler error when referencing crate "glfw-rs" () Having a dylib and an rlib simultaneously should not be a problem, it is in fact quite common. Having 2 dylibs and 1 rlib or 2 rlibs and 1 dylib however is a problem. — Reply to this email directly or view it on GitHub.
so can we close this ticket now, in that case? Or do you want to wait for alexcrichton's patches to land, and see what things look like for you then?
Nono, the ticket can be closed for now. Thanks for your help! Gesendet: Mittwoch, 19. Februar 2014 um 21:30 UhrVon: "Felix S Klock II" : mozilla/rust hhildebr : Re: [rust] Compiler error when referencing crate "glfw-rs" () so can we close this ticket now, in that case? Or do you want to wait for alexcrichton's patches to land, and see what things look like for you then? — Reply to this email directly or view it on GitHub.

Discussion:
use std::c_str::ToCStr; use std::cast; <ins> use std::hashmap::{HashMap, HashSet}; </ins> use std::cmp; use std::io; use std::os::consts::{macos, freebsd, linux, android, win32};

match self.find_library_crate() { Some(t) => t, None => { <ins> self.sess.abort_if_errors(); </ins> let message = match root_ident { None => format!("can't find crate for `{}`", self.ident), Some(c) => format!("can't find crate for `{}` which `{}` depends on",

fn find_library_crate(&self) -> Option<Library> { let filesearch = self.sess.filesearch; <del> let crate_name = self.name.clone(); </del> let (dyprefix, dysuffix) = self.dylibname(); // want: crate_name.dir_part() + prefix + crate_name.file_part + "-" <del> let dylib_prefix = format!("{}{}-", dyprefix, crate_name); let rlib_prefix = format!("lib{}-", crate_name); </del> <ins> let dylib_prefix = format!("{}{}-", dyprefix, self.name); let rlib_prefix = format!("lib{}-", self.name); </ins> <del> let mut matches = ~[]; filesearch.search(|path| { match path.filename_str() { None => FileDoesntMatch, Some(file) => { let (candidate, existing) = if file.starts_with(rlib_prefix) && file.ends_with(".rlib") { debug!("{} is an rlib candidate", path.display()); (true, self.add_existing_rlib(matches, path, file)) } else if file.starts_with(dylib_prefix) && file.ends_with(dysuffix) { debug!("{} is a dylib candidate", path.display()); (true, self.add_existing_dylib(matches, path, file)) } else { (false, false) }; </del> <ins> let mut candidates = HashMap::new(); </ins> <del> if candidate && existing { </del> <ins> // First, find all possible candidate rlibs and dylibs purely based on // the name of the files themselves. We're trying to match against an // exact crate_id and a possibly an exact hash. // // During this step, we can filter all found libraries based on the // name and id found in the crate id (we ignore the path portion for // filename matching), as well as the exact hash (if specified). If we // end up having many candidates, we must look at the metadata to // perform exact matches against hashes/crate ids. Note that opening up // the metadata is where we do an exact match against the full contents // of the crate id (path/name/id). // // The goal of this step is to look at as little metadata as possible. filesearch.search(|path| { let file = match path.filename_str() { None => return FileDoesntMatch, Some(file) => file, }; if file.starts_with(rlib_prefix) && file.ends_with(".rlib") { info!("rlib candidate: {}", path.display()); match self.try_match(file, rlib_prefix, ".rlib") { Some(hash) => { info!("rlib accepted, hash: {}", hash); let slot = candidates.find_or_insert_with(hash, |_| { (HashSet::new(), HashSet::new()) }); let (ref mut rlibs, _) = *slot; rlibs.insert(path.clone()); </ins> FileMatches <del> } else if candidate { match get_metadata_section(self.os, path) { Some(cvec) => if crate_matches(cvec.as_slice(), self.name.clone(), self.version.clone(), self.hash.clone()) { debug!("found {} with matching crate_id", path.display()); let (rlib, dylib) = if file.ends_with(".rlib") { (Some(path.clone()), None) } else { (None, Some(path.clone())) }; matches.push(Library { rlib: rlib, dylib: dylib, metadata: cvec, }); FileMatches } else { debug!("skipping {}, crate_id doesn't match", path.display()); FileDoesntMatch }, _ => { debug!("could not load metadata for {}", path.display()); FileDoesntMatch } } } else { </del> <ins> } None => { info!("rlib rejected"); </ins> FileDoesntMatch } } <ins> } else if file.starts_with(dylib_prefix) && file.ends_with(dysuffix){ info!("dylib candidate: {}", path.display()); match self.try_match(file, dylib_prefix, dysuffix) { Some(hash) => { info!("dylib accepted, hash: {}", hash); let slot = candidates.find_or_insert_with(hash, |_| { (HashSet::new(), HashSet::new()) }); let (_, ref mut dylibs) = *slot; dylibs.insert(path.clone()); FileMatches } None => { info!("dylib rejected"); FileDoesntMatch } } } else { FileDoesntMatch </ins> } }); <del> match matches.len() { </del> <ins> // We have now collected all known libraries into a set of candidates // keyed of the filename hash listed. For each filename, we also have a // list of rlibs/dylibs that apply. Here, we map each of these lists // (per hash), to a Library candidate for returning. // // A Library candidate is created if the metadata for the set of // libraries corresponds to the crate id and hash criteria that this // serach is being performed for. let mut libraries = ~[]; for (_hash, (rlibs, dylibs)) in candidates.move_iter() { let mut metadata = None; let rlib = self.extract_one(rlibs, "rlib", &mut metadata); let dylib = self.extract_one(dylibs, "dylib", &mut metadata); match metadata { Some(metadata) => { libraries.push(Library { dylib: dylib, rlib: rlib, metadata: metadata, }) } None => {} } } // Having now translated all relevant found hashes into libraries, see // what we've got and figure out if we found multiple candidates for // libraries or not. match libraries.len() { </ins> 0 => None, <del> 1 => Some(matches[0]), </del> <ins> 1 => Some(libraries[0]), </ins> _ => { self.sess.span_err(self.span, <del> format!("multiple matching crates for `{}`", crate_name)); </del> <ins> format!("multiple matching crates for `{}`", self.name)); </ins> self.sess.note("candidates:"); <del> for lib in matches.iter() { </del> <ins> for lib in libraries.iter() { </ins> match lib.dylib { Some(ref p) => { self.sess.note(format!("path: {}", p.display()));

} } } <del> self.sess.abort_if_errors(); </del> None } } } <del> fn add_existing_rlib(&self, libs: &mut [Library], path: &Path, file: &str) -> bool { let (prefix, suffix) = self.dylibname(); let file = file.slice_from(3); // chop off 'lib' let file = file.slice_to(file.len() - 5); // chop off '.rlib' let file = format!("{}{}{}", prefix, file, suffix); for lib in libs.mut_iter() { match lib.dylib { Some(ref p) if p.filename_str() == Some(file.as_slice()) => { assert!(lib.rlib.is_none()); // FIXME: legit compiler error lib.rlib = Some(path.clone()); return true; } Some(..) | None => {} } </del> <ins> // Attempts to match the requested version of a library against the file // specified. The prefix/suffix are specified (disambiguates between // rlib/dylib). // // The return value is `None` if `file` doesn't look like a rust-generated // library, or if a specific version was requested and it doens't match the // apparent file's version. // // If everything checks out, then `Some(hash)` is returned where `hash` is // the listed hash in the filename itself. fn try_match(&self, file: &str, prefix: &str, suffix: &str) -> Option<~str>{ let middle = file.slice(prefix.len(), file.len() - suffix.len()); debug!("matching -- {}, middle: {}", file, middle); let mut parts = middle.splitn('-', 1); let hash = match parts.next() { Some(h) => h, None => return None }; debug!("matching -- {}, hash: {}", file, hash); let vers = match parts.next() { Some(v) => v, None => return None }; debug!("matching -- {}, vers: {}", file, vers); if !self.version.is_empty() && self.version.as_slice() != vers { return None } debug!("matching -- {}, vers ok (requested {})", file, self.version); // hashes in filenames are prefixes of the "true hash" if self.hash.is_empty() || self.hash.starts_with(hash) { debug!("matching -- {}, hash ok (requested {})", file, self.hash); Some(hash.to_owned()) } else { None </ins> } <del> return false; </del> } <del> fn add_existing_dylib(&self, libs: &mut [Library], path: &Path, file: &str) -> bool { let (prefix, suffix) = self.dylibname(); let file = file.slice_from(prefix.len()); let file = file.slice_to(file.len() - suffix.len()); let file = format!("lib{}.rlib", file); </del> <ins> // Attempts to extract *one* library from the set `m`. If the set has no // elements, `None` is returned. If the set has more than one element, then // the errors and notes are emitted about the set of libraries. // // With only one library in the set, this function will extract it, and then // read the metadata from it if `*slot` is `None`. If the metadata couldn't // be read, it is assumed that the file isn't a valid rust library (no // errors are emitted). // // FIXME(#10786): for an optimization, we only read one of the library's //                metadata sections. In theory we should read both, but //                reading dylib metadata is quite slow. fn extract_one(&self, m: HashSet<Path>, flavor: &str, slot: &mut Option<MetadataBlob>) -> Option<Path> { if m.len() == 0 { return None } if m.len() > 1 { self.sess.span_err(self.span, format!("multiple {} candidates for `{}`  found", flavor, self.name)); for (i, path) in m.iter().enumerate() { self.sess.span_note(self.span, format!(r"candidate #{}: {}", i + 1, path.display())); } return None } </ins> <del> for lib in libs.mut_iter() { match lib.rlib { Some(ref p) if p.filename_str() == Some(file.as_slice()) => { assert!(lib.dylib.is_none()); // FIXME: legit compiler error lib.dylib = Some(path.clone()); return true; </del> <ins> let lib = m.move_iter().next().unwrap(); if slot.is_none() { info!("{} reading meatadata from: {}", flavor, lib.display()); match get_metadata_section(self.os, &lib) { Some(blob) => { if crate_matches(blob.as_slice(), self.name, self.version, self.hash) { *slot = Some(blob); } else { info!("metadata mismatch"); return None; } } None => { info!("no metadata found"); return None </ins> } <del> Some(..) | None => {} </del> } } <del> return false; </del> <ins> return Some(lib); </ins> } // Returns the corresponding (prefix, suffix) that files need to have for

} fn crate_matches(crate_data: &[u8], <del> name: ~str, version: ~str, hash: ~str) -> bool { </del> <ins> name: &str, version: &str, hash: &str) -> bool { </ins> let attrs = decoder::get_crate_attributes(crate_data); match attr::find_crateid(attrs) { None => false, Some(crateid) => { if !hash.is_empty() { let chash = decoder::get_crate_hash(crate_data); <del> if chash != hash { return false; } </del> <ins> if chash.as_slice() != hash { return false; } </ins> } name == crateid.name && (version.is_empty() ||

pub fn list_file_metadata(os: Os, path: &Path, out: &mut io::Writer) -> io::IoResult<()> { match get_metadata_section(os, path) { <del> Some(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out), None => write!(out, "could not find metadata in {}.n", path.display()) </del> <ins> Some(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out), None => { write!(out, "could not find metadata in {}.n", path.display()) } </ins> } }

<ins> // Copyright 2014 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. // no-prefer-dynamic #[crate_id = "collections#0.10-pre"]; #[crate_type = "dylib"]; </ins>

<ins> // Copyright 2014 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. // no-prefer-dynamic #[crate_id = "collections#0.10-pre"]; #[crate_type = "rlib"]; </ins>

<ins> // Copyright 2014 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. // aux-build:issue-11908-1.rs // ignore-android this test is incompatible with the android test runner // error-pattern: multiple dylib candidates for `collections` found // This test ensures that if you have the same rlib or dylib at two locations // in the same path that you don't hit an assertion in the compiler. // // Note that this relies on `libcollections` to be in the path somewhere else, // and then our aux-built libraries will collide with libcollections (they have // the same version listed) extern crate collections; fn main() {} </ins>

<ins> // Copyright 2014 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. // aux-build:issue-11908-2.rs // no-prefer-dynamic // ignore-android this test is incompatible with the android test runner // error-pattern: multiple rlib candidates for `collections` found // see comments in issue-11908-1 for what's going on here extern crate collections; fn main() {} </ins>