Question: /// # Examples /// /// ``` <del> /// #![feature(mutex_unpoison)] /// </del> /// use std::sync::{Arc, Mutex}; /// use std::thread; ///

:bell: This is now entering its final comment period, as per the . :bell:
Given the state change this method causes, I am curious about rationale behind using vs ?
If it took , it wouldn't be possible to unpoison a mutex shared between threads despite that being the main case where poisoning can happen.
I just want to add that probably before stabilizing this method we should implement a lint which catches invalid patterns of using these methods since it is very easy to misuse. Or, at the very least, include information about potential footgun in documentation for these methods.
What kind of lint do you exactly want? What are the patterns in question that you are worried about?
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.
exactly the possible error outlined by Mara Bos: calling before acquiring a lock. The only way this usage is correct is when no other thread can act on mutex - either because they don't exist or because they are all blocked on something else. I believe that these situations are rare enough to flag such a pattern as at least suspicious.
If unpoison was a method of PoisonError or of MutexGuard instead of mutex, would it prevent such problems?
That was discussed here:


Question: <ins> //! This test checks that types of up to 128 bits are returned by-value instead of via out-pointer. // compile-flags: -C no-prepopulate-passes -O // only-x86_64 #![crate_type = "lib"] pub struct S { a: u64, b: u32, c: u32, } // CHECK: define i128 @modify(%S* noalias nocapture dereferenceable(16) %s) #[no_mangle] pub fn modify(s: S) -> S { S { a: s.a + s.a, b: s.b + s.b, c: s.c + s.c } } #[repr(packed)] pub struct TooBig { a: u64, b: u32, c: u32, d: u8, } // CHECK: define void @m_big(%TooBig* [[ATTRS:.*sret.*]], %TooBig* [[ATTRS2:.*]] %s) #[no_mangle] pub fn m_big(s: TooBig) -> TooBig { TooBig { a: s.a + s.a, b: s.b + s.b, c: s.c + s.c, d: s.d + s.d } } </ins>

Rust should pass more structs in registers. Consider these examples: ideally, both functions would execute entirely in registers and wouldn't touch memory: Rust, as of a recent 1.2.0-dev nightly, is unable to pass either of these in registers (see LLVM IR and ASM below). It would be pretty safe to pass and return small structs (ones that fit into <=2 registers) in registers, and is likely to improve performance on average. This is what the System V ABI does. It would also be nice to exploit Rust's control over aliasing, and where possible also promote reference arguments to registers, i.e. put the values in registers for the following functions: In the case, this would mean passing two values in registers as function parameters, and returning two values in registers as the return values (ideally we'd arrange for the parameter registers to match the return registers). Uniqueness of makes this optimization valid, although we may have to give up on this optimization in cases such as when there are raw pointers present. Here's a more realistic example where I've wanted Rust to do this: This function is too large to justify inlining. I'd like the begin and end pointers of to be kept in registers across the function call. Probably not surprising to the compiler team, but for completeness here is the LLVM IR of the above snippets, as of today's Rust (1.2.0-dev), compiled in release mode / opt-level=3: and here is the ASM:
For fat pointers this has been fixed in Am 22.06.2015 07:58 schrieb "Reiner Pope"
On etc. this is currently impossible because the address of references is significant (you can e.g. print it with ).
- yes, the ability to take addresses prevents doing this for all functions. But you could see doing this as an optimization: make the compiler check whether a function uses the address of a reference, and if not then change its calling convention. The compiler can use the worker/wrapper technique (as in GHC) to support call sites which aren't aware of this change in calling convention, by splitting the function into two:
Don't do this. You will break FastISel. Fix LLVM if it's not doing the optimizations you want.
what exactly would break FastISel?


Question: <ins> //! This test checks that types of up to 128 bits are returned by-value instead of via out-pointer. // compile-flags: -C no-prepopulate-passes -O // only-x86_64 #![crate_type = "lib"] pub struct S { a: u64, b: u32, c: u32, } // CHECK: define i128 @modify(%S* noalias nocapture dereferenceable(16) %s) #[no_mangle] pub fn modify(s: S) -> S { S { a: s.a + s.a, b: s.b + s.b, c: s.c + s.c } } #[repr(packed)] pub struct TooBig { a: u64, b: u32, c: u32, d: u8, } // CHECK: define void @m_big(%TooBig* [[ATTRS:.*sret.*]], %TooBig* [[ATTRS2:.*]] %s) #[no_mangle] pub fn m_big(s: TooBig) -> TooBig { TooBig { a: s.a + s.a, b: s.b + s.b, c: s.c + s.c, d: s.d + s.d } } </ins>

Pretty sure that since work on niche-filling optimisation, and use a pair of registers for the argument and the return value, respectively. Cc
didn't solve this?
Yes, this appears to be fixed. The following Rust code (): generates and
Ah no, I see that this issue also suggests: We don't do that yet: . FWIW Maybe it is worth to split this issue into two. One part has been closed already AFAICT. The other part (passing as a register containing a ) is... a suggestion at most. This issue does not suggest how to do this. already raised the issue that this breaks if the address is inspected. It probably needs to handle writes through (e.g. due to ) and somehow as well, etc. So I'm skeptic that this can work.
Here's another slightly more complex example, where ABI seems to be more efficient than :
A related thread:
is this fixed? Linked code is still bigger on Rust 1.48.
my example is fixed, the return value is no longer via stack: The difference is that rust abi version now uses a vectorized add, which seems like a win?
Hi all. I've traced back the cause of 'P-high' issue to two pulls that relate to this issue, namely and . Basically, these commits break auto-vectorization post Rust version 1.48 in a way that is not easily worked around. In short, if we take: 47 yields an efficient: 48 yields an awkward: 50 yields an even more awkward cascade effect: There are other examples in . My overly simplistic analysis, I'm no expert, is . In summary, if I rebuild Rust with the above pulls neutered, auto-vectorization appears to return to normal, as per 1.47.


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

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.


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

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.


Question: } } <del> /// External iterator for a string's characters and their byte offsets. /// Use with the `std::iter` module. </del> <ins> /// Iterator for a string's characters and their byte offsets. </ins> #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct CharIndices<'a> {

eg It's still an accurate characterization, but there's no other kind to contrast with.
We probably don't need it to say "Use with the module" either.


Question: <ins> // Test that associated type bounds are correctly normalized when checking // default associated type values. // check-pass #![allow(incomplete_features)] #![feature(specialization)] #[derive(PartialEq)] enum Never {} trait Foo { type Assoc: PartialEq; // PartialEq<<Self as Foo>::Assoc> } impl<T> Foo for T { default type Assoc = Never; } trait Trait1 { type Selection: PartialEq; } trait Trait2: PartialEq<Self> {} impl<T: Trait2> Trait1 for T { default type Selection = T; } fn main() {} </ins>

So I had a trait system in my (nightly) code for a while now that utilized specialization, but it no longer seems to be working after a recent update: Now, I haven't been following the development of the specialization feature too closely, so it is possible that this is somehow actually intended and I am missing something. However, given that this previously compiled and ran just fine a couple weeks ago and given that the specialization incomplete warning was only recently, I am inclined to think that it is probably a regression of some sort. compiler version:
Another MVCE (): Regressed in , looks like
cc as far as I can tell this wasn't an intended outcome of the change?
It wasn't really, it was just slightly more complex to have this still work after that PR.
Would you mind describing at a high level what needs to be done?
It looks like the problem stems from the bound predicate not being fully normalized when checking the defaulted associated type. From my reproducer above: which should instead be . I'm not certain yet how this ought to be implemented. Perhaps a pass after normalization that looks for occurrences of the defaulted type ( in this case) and replaces it with the defaulted type. Seems simple enough, in theory :) But maybe there are cases I'm not thinking of.


Question: // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // addl_lib_search_paths <del> args.push_all(rpath::get_rpath_flags(sess, out_filename)); </del> <ins> if !sess.opts.no_rpath { args.push_all(rpath::get_rpath_flags(sess, out_filename)); } </ins> // Finally add all the linker arguments provided on the command line along // with any #[link_args] attributes found inside the crate

Currently (something after 0.5) rustc (IIUIC) is using rpaths to point libs and binaries to the appropriate locations. This is problematic when rustc and the other libs/bins are package e.g. for Fedora. The rpath usage should be made optional - can be used instead - and LDLIBRARYPATH.
Why is this problematic for packaging? Is it because the rpath values end up with the wrong values? Each crate's rpath has several values, one of which is supposed to be the final installation location (controlled with ). Can we just provide more control over which locations are used during rpathing?
In general Fedora recommends to not use rpaths [0], because the paths are hardcoded in the binary. Fedora preferres to point the dynamic linker to the appropriate paths [1]. But yes, we are more flexible about internal libraries - which the case is here. So yes, it would also help us if we could controll the rpath path (which goes a bit into the direction if issue ) [0] [1]
The following rpath is used in e.g. the cargo binary: The rpath referres to rpm's buildroot, where the lib won't stay (it will be instaled to ) Maybe the problem could adressed if the rpath would respect - but this could lead to problems at build time. Maybe LDLIBRARYPATH can be used to point to the correct dir's at build time, and the rpath can be used to point to the correct dir's at runtime. Just my 2ct - but you ar ethe expert :)
Thanks for those links. We do generate rpaths with the expectation that some of them will be invalidated by moving the binaries around. It's possible we could consider removing rpath, but it sure is nice to not think about dynamic loading when running binaries out of my build directory. We could easily add a flag to the configure script, to turn off the rpath for all the rust-provided libraries, with the assumption that package managers would modify during install. If we did that I feel like we would still want the installed rustc to generate rpaths with user-built libraries - otherwise the experience would be different depending on the rust installation. We could also just remove rpath completely - it doesn't work on windows anyway.


Question: // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // addl_lib_search_paths <del> args.push_all(rpath::get_rpath_flags(sess, out_filename)); </del> <ins> if !sess.opts.no_rpath { args.push_all(rpath::get_rpath_flags(sess, out_filename)); } </ins> // Finally add all the linker arguments provided on the command line along // with any #[link_args] attributes found inside the crate

Another thing to consider is that, if we just used rustpkg for all builds, and let rustpkg install all libraries at a known location, then we might be able to conveniently not use rpath while still doing the right thing at load time. Can user directories like be put into ?
Yes - I can fully understand how easy running rust in the build directory is when using rpaths :) For the build directory use case it should be possible to create wrappers for rustc and friends which use to point to the correct dirs. You mention thet some libs might reside in , could you explain the overall concept you are following with this? In general I'd expect libraries to appear in /lib, /usr/lib some and some private /usr/lib/myapp. There are also some xdg specs that specify and - but let usfirst see what you say about ~/.rustpkg. Oh, I don't think that ~/.rustpkg would be expanded correctly if put into
Just to summarize my thoughts: If rpath is used, the rpath path beeing used should only use directories below (to point to non-standard dirs containing libs relevant for a rust component). The rpath path should not point to any build-time dir. To include libraries at buildtime or when using the binaries in the build directory I'd suggest using wrappers (isn't autotools doing it like this?) which set appropriately.
Any follow up thoughts?
Our package manager will by default not be installing libraries to a system location and will instead put them in the user's directory, . This doesn't seem out of the ordinary to me; consider cabal, etc. The behavior you recommend requires some deep changes to how Rust works, so need to be considered carefully. Does the current behavior prevent packaging in Fedora, and is there a minimal change we can make to unblock packaging? You'll probably be interested in this subject.
Thanks for the rustpkg explanation. Do I understand that rustpkg will create binaries and libs with rpaths pointing to the user's specific rustpkg dir ? My feeling is that this user specific rpaths should be configurable at build time. The use case is obviously when the binary or lib is going to be installed systemwide. The only rpath exception is the rpath pointing to the system wide package specific libdir (e.g. ).


Question: // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // addl_lib_search_paths <del> args.push_all(rpath::get_rpath_flags(sess, out_filename)); </del> <ins> if !sess.opts.no_rpath { args.push_all(rpath::get_rpath_flags(sess, out_filename)); } </ins> // Finally add all the linker arguments provided on the command line along // with any #[link_args] attributes found inside the crate

I think that I'll spend a bit more time with looking at and and might get a better feeling for the problem. Btw.: I noted that the libdir isn't configurabel. Fedora for example keeps x86_64 libs in (/usr)?/lib64, and i686 in (/usr)/lib. IIUIC this is currently not possible with rust as the libs will be installed to /usr/lib/arch-specific-path
The point about libdir is well taken and I updated . I am not entirely sure how rustpkg does it's build now or how and intend for it to work, but based on the current language design I would expect that, yes, binaries installed to would have rpaths pointing there. Currently there are several rpaths configured for each linked library so that they hopefully fall back to something useful when the libraries are moved around during install or during the bootstrapping process, something like: The relative path to the library The absolute path to where the library was at build time The system installation path Under this scheme I would expect that would, when linking against libraries in , create rpaths to .
Yes, there are several rpaths used (seen in and ) and I'd say - even with looking at rust itself, without the packaging glasses on - that it should be configurable what rpaths are used. Maybe it should be an option of . As said, system wide binaries are the best example for binaries where you don't want to many rpaths - including no rpaths pointing to some user dir.
Please don't tag TJC :(
Sorry, TJC! Maybe it's time to give in and start working on Rust :) Seriously though, sorry. I'm sure it's a real PITA.
mentioned that this is a security issue, which I didn't realize. Debian also says .
By the way, it's possible to strip this with but it would be much nicer to not require a third party tool.
I generally wonder why you don't add a user-specific to to point to the user specific rustpkg dir instead of using rpath. That makes it much easier to cope with - and that would also be in par with (at least) the Fedora guidelines. And I suppose with Debian's too, as it's the common way. (See 3rd party java binaries. They modify the to point to some hidden dir in the userdir.)
We used to.


Question: // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // addl_lib_search_paths <del> args.push_all(rpath::get_rpath_flags(sess, out_filename)); </del> <ins> if !sess.opts.no_rpath { args.push_all(rpath::get_rpath_flags(sess, out_filename)); } </ins> // Finally add all the linker arguments provided on the command line along // with any #[link_args] attributes found inside the crate

Users kept forgetting and/or getting annoyed having to adjust it when running from a build dir. Rpaths made it possible to run foo/bar/rustc no matter which rustc you chose.
right. IIUIC - I always feel like a noob when it comes to autotools - autotools are generating wrappers for binaries which are created during a build process and moves the original binaries to hiddend irectories. The wrappers are then modifying the environment (setting env vars etc) to achieve the same goal (so e.g. that rustc can be run from the dev directory without messing with the env vars yourself). I wonder if this could help.
Okay, it's actually not autools which creates these wrappers but libtool:
Sorry, I didn't mean to imply a disinterest in fixing this better, just noting how it came to be. Also strongly disinterested in using libtool. Would prefer going back to telling users to set env vars.
How about defaulting to static linking (when it works)? Dynamic linking is valuable, but mostly for global installs handled by a package manager. Of course, if we end up with a bunch of tools using that would be wasteful. I think RPATH will just lead to confusion, and it's an easy security hole to leave open.
I would be very happy to get static linking working well enough to make it a default in many such cases. But we ought to do the right thing when linking dynamically too. Is rpath-using- considered acceptable? I.e. is it just the absolute paths that are problematic?
The absolute paths are the ones that can easily be a security issue, so isn't that bad. I would still rather avoid it for a globally installed package but it's easy enough to strip for people who don't need it and won't be an issue if you don't know about it (like the absolute path could be). Using the rpath could be a flag, but the absolute path should never be there.
Nominating for milestone 2: backwards compatible. (The choice of whether one needs to put a setting in or use some configure flag for certain systems, etc, seems like a backwards compatibility issue. Though maybe I misunderstand and these are issues only for people developing itself, not for clients of ?) It also could well be that this is more appropriately assocated with milestone 1: well-defined.


Question: // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // addl_lib_search_paths <del> args.push_all(rpath::get_rpath_flags(sess, out_filename)); </del> <ins> if !sess.opts.no_rpath { args.push_all(rpath::get_rpath_flags(sess, out_filename)); } </ins> // Finally add all the linker arguments provided on the command line along // with any #[link_args] attributes found inside the crate

I suspect and have a more concrete notion about this.
I don't have anything much to add to this despite it coming up for triage today. I think it has to be fixed still, I'm still happy to do it via whatever combination of static linking by default and use of is sufficient for packagers, and I haven't seen any clear movement on it in the meantime.
accepted for backwards-compatible milestone
I'm getting worried that we won't resolve this for 1.0. I agree this is important to fix. Here's my current suggestion: Modify the build system to once again set LDLIBRARYPATH/PATH to find the appropriate dynamic libraries. Add a flag to rustc to disable rpath Add a configure flag to disable rpathing the rust build itself. Packagers can use this to do whatever they want. With this logic the rust package itself could avoid rpath where distros have their own way of dealing with library paths. The rustc installed by these distros would still be rpathing user's crates for the sake of convenience. Is this an acceptable compromise or do distros want us to completely disable rpath? I'm afraid that doing so would provide an inconsistent developer experience depending on how rustc is acquired; if we need to do that then we instead must find a way to completely eliminate rpath.
If we start to just statically link everything by default then rpath becomes much less important and we can just say it's up to users to figure it out if they opt into dynamic linking.
I think we should completely remove absolute rpaths. It's okay to have $ORIGIN-based ones but it may not be a good default. I'm not sure what the answer is to that, but agree that static linking basically resolves this.
It doesn't appear that this is fully working. There are still rpaths in the binaries when configured with even though the flag for rustc does work. /usr/bin/rustc: RPATH=$ORIGIN/../lib:/build/rust-git/src/rust/x8664-unknown-linux-gnu/stage1/lib/rustlib/x8664-unknown-linux-gnu/lib:/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib
What steps did you follow to having the rpath show up? I thought I double checked on linux that the configure flag worked, but I may have overlooked something.


Question: impl<'tcx> GATSubstCollector<'tcx> { fn visit<T: TypeFoldable<'tcx>>( <ins> tcx: TyCtxt<'tcx>, </ins> gat: DefId, t: T, ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) { <del> let mut visitor = GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() }; </del> <ins> let mut visitor = GATSubstCollector { tcx, gat, regions: FxHashSet::default(), types: FxHashSet::default(), }; </ins> t.visit_with(&mut visitor); (visitor.regions, visitor.types) }

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Slightly minimized:
I understand the issue here, and have a solution but it might not be optimal. claim


Question: fn poll_write( self, cx: &mut Option<String>,  buf: &mut [usize]   buf: &mut [usize],  ) -> Option<Result<usize, Error>>;     fn poll_flush(self, cx: &mut Option<String>) -> Option<Result<(), Error>>;     fn poll_close(self, cx: &mut Option<String>) -> Option<Result<(), Error>>;

Take a look at the docs for : Rustdoc is making good choices for whether to wrap the declarations ! But when it wraps, it doesn't include a trailing comma on the last parameter. I think it should, because the default style guide wants a comma there. (And rustdoc should continue not putting a trailing comma when the declaration is shown as a single line.) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim


Question: fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> { let mut ty = self.typeck_results.node_type(pat.hir_id); <del> if let ty::Error(_) = ty.kind { // Avoid ICEs (e.g., #50577 and #50585). return Pat { span: pat.span, ty, kind: Box::new(PatKind::Wild) }; } </del> let kind = match pat.kind { hir::PatKind::Wild => PatKind::Wild,

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --produces an ICE for the code given below. This code should produce an error (the implementation is missing associated items). (UPDATED: Here's MCVE: ) <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: Error also occurs on beta and nightly. <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Thanks! Further minimized:
Assigning as and removing .
Don't know the cause yet, but if you remove the keyword or the operator, then you get this error: My hunch is that somehow, lacking those items, the type of is coming up with something that doesn't implement the expected traits -- I would bet that we are getting an , based on some of the output at the end. Perhaps some of the logic in MIR is failing as a result. The actual ICE location though isn't that illuminating:
I did some digging here. The source of the panic is here, during HAIR construction: In this case, the binding below is of the error type (meaning type check for it failed). By replacing the binding with `` we prevent a local from being created for it, which means that when we try to generate code that reads the local we get a panic . I'm not sure what the correct fix is here. Replacing the binding with was done to prevent other ICEs, but we can't generate valid MIR without the local info. More fundamentally: We're building MIR during typeck because this is an async fn. In the past we probably never would have gotten to this stage. Backtrace: <details</details


Question: to `int`s, though. We can make it usable by any type, but we haven't quite gotten there yet! <del> You can have any number of values in an enum: </del> <ins> You can also have any number of values in an enum: </ins> ```{rust} enum OptionalColor {

See: The keyword hasn't been introduced until that point but it's used in the code example which is confusing. I believe an if/else solution would be more explanatory, especially because the reader probably wants to see how to unpack the variant of . The same enum could then be used with the keyword in the beginning of the next chapter ().
You are correct. Nice catch!
Are you ok with simply reordering them ? Because introducing sum type without precedent knowledge of pattern matching is a bit pointles (or at least misses the fact that they are juste AWESOME for pattern matching). If you're ok with this I'll PR in a few hours :)
Maybe, if it flows okay, yeah. I do want to put SOME kind of mention of it first.
It's probably easy to find out what is doing by simply looking at it. This part of the tutorial is just a bit confusing and should be fixed. However, my main concern here is that the reader is left clueless on how to solve this problem with if/else: In fact, I really don't know how the equivalent code without would look like. I've briefly tried to figure it out and gave up.
With an Option you coul unwrap I guess. By the way why did you write a fake option enum ? Because that's basically what is done with this, it might be better to give out the real name
Because we haven't talked about generics yet.
Nicely done. However, my other concern, how this example could be done without , remains unresolved. I'm certain that I'm not the only one who wants to know how it works with before continue reading about . Should I open another issue for that matter?
I'm honestly not sure that it is possible with an arbitrary enum... You can test for some arbitrary values but i guess but that's it. Bt it's more an issue of sum types in general rather than a Rust issue (I can't find ways to do that in haskell nor in scala)
Alright, I expected something like this as I was unable to figure out how to write it without . I don't have much experience with statically typed languages, therefore the concept was new to me. If you are right, could we mention in the tutorial that it is actually not possible to write an equivalent solution with ? Certainly, I can't be the only one who was a bit puzzled.


Question: to `int`s, though. We can make it usable by any type, but we haven't quite gotten there yet! <del> You can have any number of values in an enum: </del> <ins> You can also have any number of values in an enum: </ins> ```{rust} enum OptionalColor {

Cheers.
Thanks a lot for the remark, it's exactly the kind of comment needed, if you see others don't hesitate to open new issues :) I'll try to add this tonight or tomorrow.


Question: // Regression test for issue #4935 fn foo(a: usize) {} <del> fn main() { foo(5, 6) } //~ ERROR this function takes 1 parameter but 2 parameters were supplied //~^ NOTE the following parameter type was expected </del> <ins> fn main() { foo(5, 6) } //~^ ERROR this function takes 1 parameter but 2 parameters were supplied //~| NOTE the following parameter type was expected //~| NOTE expected 1 parameter </ins>

From: src/test/compile- Error E0061 needs a span_label, updating it from: To: Bonus: the types could be incorporated into the label rather than a note (though we may want to avoid types with long names in the label)
Planning on tackling the bonus here. Is there a prefered max length for output on the console. In the case it would exceed this should i truncate the typename or just not include?
- great point. If you want to work on truncation, feel free to add it, too. I'm not sure if the term crate will tell you the current terminal size, but it may.
I'm fixing and I noticed that it and this issue currently share the same code for generating this error, and adding code to add a to the message in would fix both.
Did you do the bonus as well? I can tackle that if you haven't.
I haven't yet - I can fix the issue (currently testing/fixing unit tests) and you can take on the bonus part of the issue.
Sounds great to me! Thanks.
- I opened up issue to track the bonus portion of the work for you.


Question: <ins> // check-pass // This is currently stable behavior, which was almost accidentally made an // error in #102161 since there is no test exercising it. I am not sure if // this _should_ be the desired behavior, but at least we should know if it // changes. fn main() {} trait Foo { fn fn_with_type_named_same_as_local_in_param(b: i32, b: i32); } </ins>

Example: yields <details<summaryBacktrace</summary</details
cc and
This has to do with late-bound regions and RPITITs. I have a fix, but it's probably not right nor is it cleaned up much. I'll put it up for scrutiny soon though.
Actually nvm, it was a silly little resolver bug.
label +I-ICE +C-bug


Question: <ins> // check-pass // This is currently stable behavior, which was almost accidentally made an // error in #102161 since there is no test exercising it. I am not sure if // this _should_ be the desired behavior, but at least we should know if it // changes. fn main() {} trait Foo { fn fn_with_type_named_same_as_local_in_param(b: i32, b: i32); } </ins>

I'm seeing an internal compiler error on the following input (found by ):
Report from : regressed nightly: nightly-2020-02-07
It looks like caused the regression. (The error happens at but not at .) cc
The specific commit where the error starts happening is .
triage: P-high. Removing nomination. Added regression stable-to-nightly tag.
Fixed by


Question: <ins> error: Unexpected `@` in struct pattern --> $DIR/at-in-struct-patterns.rs:8:15 | LL |     let Foo { var @ field1, .. } = foo; |         ---   ^^^^^ |         | |         while parsing the fields for this pattern | = note: struct patterns use `field: pattern` syntax to bind to fields = help: consider replacing `new_name @ field_name` with `field_name: new_name` if that is what you intended error: `@ ..` is not supported in struct patterns --> $DIR/at-in-struct-patterns.rs:10:26 | LL |     let Foo { field1: _, bar @ .. } = foo; |         ---              ^^^^^^^^ |         | |         while parsing the fields for this pattern | help: bind to each field separately or, if you don't need them, just remove `bar @` | LL -     let Foo { field1: _, bar @ .. } = foo; LL +     let Foo { field1: _, .. } = foo; | error: `@ ..` is not supported in struct patterns --> $DIR/at-in-struct-patterns.rs:11:15 | LL |     let Foo { bar @ .. } = foo; |         ---   ^^^^^^^^ |         | |         while parsing the fields for this pattern | help: bind to each field separately or, if you don't need them, just remove `bar @` | LL -     let Foo { bar @ .. } = foo; LL +     let Foo { .. } = foo; | error: expected identifier, found `@` --> $DIR/at-in-struct-patterns.rs:12:15 | LL |     let Foo { @ } = foo; |         ---   ^ expected identifier |         | |         while parsing the fields for this pattern error: expected identifier, found `@` --> $DIR/at-in-struct-patterns.rs:13:15 | LL |     let Foo { @ .. } = foo; |         ---   ^ expected identifier |         | |         while parsing the fields for this pattern error[E0425]: cannot find value `var` in this scope --> $DIR/at-in-struct-patterns.rs:9:10 | LL |     dbg!(var); |          ^^^ not found in this scope | help: consider importing this function | LL + use std::env::var; | error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0425`. </ins>

This erroneous code: Produces this error message It would be better if instead it produced an error message like this: Tried the code in these Rust versions and they all produced the same error message: 1.37.0 stable1.45.0 stable1.46.0-beta.1 (2020-07-15 )1.47.0-nightly (2020-07-22 ) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
This shouldn't be too hard. This comes from the parser, specifically the code that parses a pattern, which is one of functions. Somewhere there is the code to parse a struct pattern. I assume the error above happens when it successfully parses a struct field and then expects a comma or closing brace. To fix it you'd have to check for and report a better error message.
claim


Question: <ins> // Copyright 2015 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. // error-pattern: expected item, found `parse_error` include!("../auxiliary/issue-21146-inc.rs"); fn main() {} </ins>

Testcase: : : Output: Should output, instead, the parse errors from . Probably misplacing the diagnostic emitter somehow, when creating the nested parser for the included source, and doesn't have an .
(I suspect this is an easy fix, but am not quite sure)


Question: this.pat_bindings(&**pat, |this, ln, var, sp, id| { this.warn_about_unused(sp, id, ln, var); }); <ins> visit::walk_expr(this, expr); </ins> } // no correctness conditions related to liveness

compiles without a peep, even though and are unused. Commenting out the gives the expected output:
I think this an be closed
Thanks (fixed in )


Question: impl Foo for u32 { fn len(&self) -> u32 { *self } <del> //~^ ERROR incompatible type for trait: expected unsafe fn, found normal fn </del> <ins> //~^ ERROR method `len` has an incompatible type for trait //~| expected unsafe fn, //~| found normal fn </ins> } fn main() { }

The multi-line errors should be extended to include this testcase. missed this because the didn't go through . I tried but that didn't work either. If someone can point me to to where to catch it, I can probably fix this too. cc Code: Error: Change to:


Question: /// impl Gadget { ///     /// Construct a reference counted Gadget. ///     fn new() -> Rc<Self> { <del> ///         Rc::new_cyclic(|me| Gadget { me: me.clone() }) </del> <ins> ///         // `me` is a `Weak<Gadget>` pointing at the new allocation of the ///         // `Rc` we're constructing. ///         Rc::new_cyclic(|me| { ///             // Create the actual struct here. ///             Gadget { me: me.clone() } ///         }) </ins> ///     } /// ///     /// Return a reference counted pointer to Self.

As I in the i.r-l.o prerelease thread, the documentation of the new(ly stabilized) and method could really use some elaboration before the 1.60 release. I'm quite familiar with refcounting, strong/weak refs, etc. but just from the doc, I have no idea what problem the new method solves exactly, when I should use it, why the closure is needed, how the closure argument seems to come from "thin air", and what the closure should return.
Argh, thanks. Could've sworn I specifically double-checked that I wrote "cyclic"…
Problem the method solves: constructing a which holds a pointer to itself. When you should use it: when you need to do the above. Previously you'd construct with e.g. and then mutate the value (via e.g. ) to fix up the self references. Where the closure argument comes from: essentially, the point of is that the place is allocated first, with strong=0, weak=1. The place has no data yet (you're constructing the value to place there), but is in the "zombie" state where it has weak references but no data. Why the closure is needed: the place needs to be "finished" once the value is created. In theory, you could "recover" any zombie weak, but for the most case, Rust wants to pretend that a "zombie" and a dangling are equivalent. What the closure should return: the closure returns the object to place in the reference counted place. After you've constructed the object, the reference count is "activated" and the object is accessable by (clones of) the weak pointer given to the constructor closure. For the most part, exists to construct style objects more easily, which is what the example demonstrates. It can be used for other use cases, but this is the primary motivating example. I'm biased because I know what is used for, so the existing documentation is enough. The docs aren't going to be changed for 1.60, but if you (or anyone) can improve the docs (with the above information or otherwise), PRs to do so are welcome!
I agree I had to read the documentation a few times to understand what this does.
Hi!


Question: /// impl Gadget { ///     /// Construct a reference counted Gadget. ///     fn new() -> Rc<Self> { <del> ///         Rc::new_cyclic(|me| Gadget { me: me.clone() }) </del> <ins> ///         // `me` is a `Weak<Gadget>` pointing at the new allocation of the ///         // `Rc` we're constructing. ///         Rc::new_cyclic(|me| { ///             // Create the actual struct here. ///             Gadget { me: me.clone() } ///         }) </ins> ///     } /// ///     /// Return a reference counted pointer to Self.

Just a quick note that changing the documentation for the Rust 1.60.0 release itself will likely not be possible, that'd require a full release rebuild.
I'm sending a PR with explanations provided by so that it'll at least be in the next release. Why do you need a full release rebuild btw? Isn't it possible to regen the docs without rebuilding everything like the option on rustc?
I opened Feedback is very welcome. :)
Our release tooling only supports building everything at the same time.
Well, at least it'll be present in the next release with a beta backport.


Question: } } <del> inline(cx, llfn, codegen_fn_attrs.inline.clone(), instance.def.requires_inline(cx.tcx)); </del> <ins> let inline_attr = if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { InlineAttr::Never } else if codegen_fn_attrs.inline == InlineAttr::None && instance.def.requires_inline(cx.tcx) { InlineAttr::Hint } else { codegen_fn_attrs.inline }; inline(cx, llfn, inline_attr); </ins> // The `uwtable` attribute according to LLVM is: //

Currently, the compiler is allowed to inline naked functions if it wants to. For a normal function, inlining is fine because the compiler can remove the function prologue/epilogue and the remaining will behave as expected. However for naked functions, the developer provides the prologue/epilogue and those aren't removed by the compiler. This almost surely will result in incorrect behavior. Accordingly I think it would make sense for the compiler to not inline naked functions unless the developer explicitly opted-in.
In the other thread, alistair23 found that
Yes, functions should imply .


Question: expr_is_from_block, ); } <ins> MustUsePath::Pinned(path) => { let descr_pre = &format!("{descr_pre}pinned "); emit_must_use_untranslated( cx, path, descr_pre, descr_post, plural_len, true, expr_is_from_block, ); } </ins> MustUsePath::Opaque(path) => { let descr_pre = &format!("{descr_pre}implementer{plural_suffix} of "); emit_must_use_untranslated(

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --Defining traits that contain methods that return such a type: The compiler should probably have warned me about not using the of the , consistent with the behaviour of async functions in Rust 1.67.0. This will also work without the need for traits but async traits is one of the most common use cases for such a type. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
We looked at this as the wg-async triage meeting today. We agree this is a bug and that the behavior should be consistent with on and/or . This is also likely a good first issue for someone wanting to contribute to async.
Would you say this is also a good issue for a first-time contributor to Rust? I'm not super familiar with the language, but I want to contribute to open source compilers, so I'm hoping to potentially take on this task.
Can I take this ?
Either one of you ( or are welcome to work on this! If it's your first time contributing to Rust, it might take a while to ramp up on it, but I find the best way to do that is to just do it. If you decided to have a go at it, feel free to ask any questions you have either here or in . I tend to watch #wg-async closer than GitHub issues, so you'll probably get a more prompt reply there.
this issue wasn't claimed so you are free to claim and work on it if you still are interested. Kindly comment with to claim the issue.
claim
This is also a very special case of


Question: self.output); } } <del> mir::Rvalue::Box(_) => { </del> <ins> mir::Rvalue::Box(..) => { </ins> let exchange_malloc_fn_def_id = self.scx .tcx()

I found that current rustc 1.13.0-nightly can't compile'Rust by Example - 8.2.5 As output parameters' code, both on my linux pc and . I tried this code: see Executing code above on Rust Playground produces the message below when selecting nightly. ( but stable and beta do not produce this error). error: linking with failed: exit code: 1 | = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib" "./out.0.o" "-o" "./out" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libstd-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libpanicunwind-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libunwind-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/librand-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libcollections-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/librustcunicode-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/liballoc-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/liballocjemalloc-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/liblibc-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libcore-" "-l" "dl" "-l" "pthread" "-l" "gccs" "-l" "pthread" "-l" "c" "-l" "m" "-l" "rt" "-l" "util" "-l" "compiler-rt" = note: ./out.0.o: In function drop::hf3564cae7b79f1cb': (.text.


Question: self.output); } } <del> mir::Rvalue::Box(_) => { </del> <ins> mir::Rvalue::Box(..) => { </ins> let exchange_malloc_fn_def_id = self.scx .tcx()

ZN4drop17hf3564cae7b79f1cbE+0xd): undefined reference toLTGTasGT$::drop::h4c07c16183524d21' ./out.0.o: In function drop::hc5f0e028c3876d25': (.text.ZN4drop17hc5f0e028c3876d25E+0xd): undefined reference toLTGTasGT$::drop::h7a8bb753832b1af2' collect2: error: ld returned 1 exit status error: aborting due to previous error Compilation failed. This happens on my Linux Laptop pc as well. This is my laptop's rustc version(installing current latest) . : rustc 1.13.0-nightly ( 2016-08-25) binary: rustc commit-hash: commit-date: 2016-08-25 host: x86_64-unknown-linux-gnu release: 1.13.0-nightly
Nominating since this appears to be a regression.
is still good, does not exist and fails. . Reduced:
This may be a related to . Edit: not a duplicate I think, since was introduced in a different nightly.
Running with the above sample and leads to an ICE in printing a log message
This is from the removal of old trans. We should've been covered by on-demand drop glue generation still, though. cc
Looking at the IR - the missing methods are d, and called from drop methods taking e.g.
Oh, this is bad. The collector needs to know user definitions being instantiated ahead of time (including impls), and these can be used from drop glue which is not guaranteedly known ahead of time. We might need to temporarily detect the shim'd cases in the collector and trigger drop glue generation. cc
I'm looking into a short-term fix right now.
yay! Thanks


Question: error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates <del> --> $DIR/impl-unused-tps.rs:13:8 </del> <ins> --> $DIR/impl-unused-tps.rs:15:8 </ins> | LL | impl<T,U> Foo<T> for [isize;1] { |        ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates <del> --> $DIR/impl-unused-tps.rs:30:8 </del> <ins> --> $DIR/impl-unused-tps.rs:31:8 </ins> | LL | impl<T,U> Bar for T { |        ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates <del> --> $DIR/impl-unused-tps.rs:38:8 </del> <ins> --> $DIR/impl-unused-tps.rs:39:8 </ins> | LL | impl<T,U> Bar for T |        ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates <del> --> $DIR/impl-unused-tps.rs:46:8 </del> <ins> --> $DIR/impl-unused-tps.rs:47:8 </ins> | LL | impl<T,U,V> Foo<T> for T |        ^ unconstrained type parameter error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates <del> --> $DIR/impl-unused-tps.rs:46:10 </del> <ins> --> $DIR/impl-unused-tps.rs:47:10 </ins> | LL | impl<T,U,V> Foo<T> for T |          ^ unconstrained type parameter <del> error: aborting due to 5 previous errors </del> <ins> error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]` --> $DIR/impl-unused-tps.rs:27:1 | LL | impl<T> Foo<T> for [isize;0] { | ---------------------------- first implementation here ... LL | impl<T,U> Foo<T> for U { | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]` error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`) note: required for `([isize; 0], _)` to implement `Bar` --> $DIR/impl-unused-tps.rs:31:11 | LL | impl<T,U> Bar for T { |      -    ^^^     ^ |      | |      unsatisfied trait bound introduced here = note: 126 redundant requirements hidden = note: required for `([isize; 0], _)` to implement `Bar` error: aborting due to 7 previous errors </ins> <del> For more information about this error, try `rustc --explain E0207`. </del> <ins> Some errors have detailed explanations: E0119, E0207, E0275. For more information about an error, try `rustc --explain E0119`. </ins>

No response No response No response
(for compiler people:) We could fix this by merging the impl WF and coherence checks into one compiler stage. I'll put up a PR and see what T-types thinks.
labels +AsyncAwait-Triaged We discussed this in a WG-async meeting and are deferring to the resolution suggested above. He noted that this is a fix to the diagnostics only. That fact that this is an error is correct.


Question: sig: ty::PolyFnSig<'tcx>, tuple_arguments: TupleArgumentsFlag, ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> { <ins> assert!(!self_ty.has_escaping_bound_vars()); </ins> let arguments_tuple = match tuple_arguments { TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), }; <del> debug_assert!(!self_ty.has_escaping_bound_vars()); </del> let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]); sig.map_bound(|sig| (trait_ref, sig.output())) }

An there actually does panic for the test. I only moved this code between the files, the same comment and code pattern exists as well for normal closures: Originally posted by in
I couldn't repro this failure, maybe was doing instead of ? The ordering is important here.
I believe I did, yes.


Question: } } <del> pub fn retokenize(sess: &'a ParseSess, mut span: Span) -> Self { let begin = sess.source_map().lookup_byte_offset(span.lo()); let end = sess.source_map().lookup_byte_offset(span.hi()); // Make the range zero-length if the span is invalid. if begin.sf.start_pos != end.sf.start_pos { span = span.shrink_to_lo(); } let mut sr = StringReader::new(sess, begin.sf, None); // Seek the lexer to the right byte range. sr.end_src_index = sr.src_index(span.hi()); sr } </del> fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span { self.override_span.unwrap_or_else(|| Span::with_root_ctxt(lo, hi)) }

contains a function, which allows to to, well, retokenize existing span: There's only caller of this function: And there's only one caller of that caller: In other words, the only reason why we need is to get the span of hir::Usewhich happens to be a glob import. ( rls needs to know the span of use foo:: with explicit list of imported items" code action. This was the first demoed code action and is still that is implemented ) I'd like to remove the function, as it is one of the few remaining things that requires to be public, and as it is very much a hack anyway. Additionally, I believe I've broken this function accidently a while ago: Rather than retokenizing a span, it retokenized file from the begining until the end of the span (whcih, as uses are usually on top, worked correctly most of the times by accident). What would be the best way to fix this? Add hir::Use-- this seem to be the "proper" solution here Move hack's implementation to where it belongs: in , just fetch the text of the file and look for ('') Remove the deglog functionlity from RLS? I don't like this option as it handicaps the RLS before we formally decided to deprecated it. But I don't completely disregard it either, as, as a whole, it seems to be a full-stack one off hack penetrating every layer of abstraction. WDYT?
I'd suggest the second alternative (move hack's implementation to in librutcsaveanalysis), save analysis is a home of many hacks already and one more until save analysis is deprecated in its entirety won't hurt. Adding span for would be ok if it were useful for anything else at least.


Question: /// # Examples /// /// ``` <del> /// #![feature(osstring_ascii)] </del> /// use std::ffi::OsString; /// /// let mut s = OsString::from("Grüße, Jürgen ❤");

<!-- Thank you for creating a tracking issue! Tracking issues are for tracking a feature from implementation to stabilization. Make sure to include the relevant RFC for the feature if it has one. If the new feature is small, it may be fine to skip the RFC process. In that case, you can use use in your initial implementation PR. The reviewer will ask you to open a tracking issue if they agree your feature can be without an RFC. --Feature gate: <!-- For most library features, it'd be useful to include a summarized version of the public API. (E.g. just the public function signatures without their doc comments or implementation.) --<!-- For larger features, more steps might be involved. If the feature is changed later, please add those PRs here as well. --- [x] - Stabilized traits necessary to obtain [x] - Added ASCII methods on [x] Final commenting period (FCP) [x] - Stabilization PR <!-- Once the feature has gone through a few release cycles and there are no unresolved questions left, the feature might be ready for stabilization. If this feature didn't go through the RFC process, a final commenting period (FCP) is always needed before stabilization. This works as follows: A library team member can kick off the stabilization process, at which point the rfcbot will ask all the team members to verify they agree with stabilization. Once enough members agree and there are no concerns, the final commenting period begins: this issue will be marked as such and will be listed in the next This Week in Rust newsletter. If no blocking concerns are raised in that period of 10 days, a stabilzation PR can be opened by anyone. --<!-- Include any open questions that need to be answered before the feature can be stabilised. If multiple (unrelated) big questions come up, it can be a good idea to open a separate issue for each, to make it easier to keep track of the discussions. It's useful to link any relevant discussions and conclusions (whether on GitHub, Zulip, or the internals forum) here. --- None yet.
Just needed to manipulate paths on windows -- I need to lower case driver letter, -.
Currently, SQLx contains The UTF-8 check that is included in there, while not a problem in practice, seems pointless. Changing to lands me here because of the .


Question: /// # Examples /// /// ``` <del> /// #![feature(osstring_ascii)] </del> /// use std::ffi::OsString; /// /// let mut s = OsString::from("Grüße, Jürgen ❤");

Also, if somebody did a similar thing with instead of , the version could drop that and would then be a bit less noisy.
is a stabilization PR. Since lib team wants to do fcp in the tracking issue. could you start one ?
merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [x] [x] [ ] Concerns: resolved by Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
Slight question about -- normally when dealing with AsRef args, they come in without an explicit reference in the signature (), except when necessary to support a lifetime in the return value (). Currently is declared as: Is this supposed to be instead? concern eqignoreasciicase &S
I think it should be. I'm not sure why I wrote it like I did originally, but this makes more sense to me. I can make that PR if needed. Or can it be done in the stabilization PR? Not sure what the process is from here.
resolve eqignoreascii_case &S reviewed Fixed in .
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon.
you can tick the FCP box, as the FCP is complete.


Question: self.super_terminator(terminator, location); match &terminator.kind { <del> TerminatorKind::Call { func, .. } => { </del> <ins> TerminatorKind::Call { func, args, .. } => { </ins> let ConstCx { tcx, body, param_env, .. } = *self.ccx; let caller = self.def_id().to_def_id();

The panic payload of the macro (as passed on to ) is generic, but the CTFE panic support assumes it will always be an . This leads to ICEs: Cc
I guess we could support this, but we'd have to find some way to render the errors. Maybe we need to wait for const traits so we can require const Debug?
Alternatively constck could require the argument to have type .
also requires a
Yeah, the libcore panic machinery does not support non-format-string panics.
Aye, left out the latter of my message. is likely the most common argument to , and it's not unusual with e.g. ; so I agree that waiting for const traits before supporting any other arguments is reasonable.
Im hitting this ICE on stable without feature flag:
Hm indeed, that is interesting: any idea why we go on here after seeing an error? Does this kind of behavior mean any part of CTFE is reachable on stable somehow?
yes. We're not gating CTFE on whether there were stability (or any other static checks) failing. I've been abusing this since 1.0 to demo things on the stable compiler and never got around to fixing it. I don't even know if we have a tracking issue for it.
:rofl: So what would be a possible approach here? Replace such consts by early enough that their MIR never actually gets evaluated? We might as well use this issue, IMO...
That would require us to mutate all MIR and potentially even HIR. Other possible solutions: poison the mir Body if const checks fail (by adding a field like or by just nuking the body by replacing it with ) and thus make allow const evaluation to check if the mir Body failed the checks and bail out before doing anything make the have an field similar to
On second thought, let's leave this issue for the ICE, and make a new one for "we can trigger nightly-only const code on stable because we don't abort compilation early enough":
Given that this ICE is pre-existing, as shown by , can we un-block ? I'd really like to see const_panic stabilized, and this seems like a minor issue to be blocking on.
That comment is an example of accidentally partially exposing an unstable feature on stable -- a separate bug tracked in I don't see how that's an argument for shipping that feature on stable when it is broken.


Question: self.super_terminator(terminator, location); match &terminator.kind { <del> TerminatorKind::Call { func, .. } => { </del> <ins> TerminatorKind::Call { func, args, .. } => { </ins> let ConstCx { tcx, body, param_env, .. } = *self.ccx; let caller = self.def_id().to_def_id();

In particular, applies to all unstable const features. Fixing this bug here is not even that hard I think: somewhere around here there needs to be a check that the argument has type . Re: , AFAIK that one is also blocked on figuring out how the diagnostics should look like, and a further concern (though maybe not blocking) is .
I guess that might make this a non-issue, where it is proposed also would require as first argument.
For reference: , which was recently merged. The plan is to fix the behaviour of in the Rust 2021 edition. Given that this ICE is listed as a blocker for , does this mean that stabilizing that will have to wait for the next edition?
No, because breaking changes are allowed to be made to unstable features without moving to a new edition; that's kinda the whole idea. The 2021 edition will effectively just extend the same restriction to all invocations, const context or not.
I'd like to tackle this but I'm not very experienced with the CTFE code. I get that we need to check from the that we've matched on in this branch and we need to match on the enum, but: For the first question, I see and that we probably want to check that the type of the tuple and that there's variants of that are , but do we stop the iteration when we get one that is a type? Is the projection list always guaranteed to terminate in a variant of that has a ? And once we have an instance of , do we just check that there's any_ projection in the list that has a ?
you can use to get the type of the . Then you can test its to be .


Question: 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()));

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.


Question: 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()));

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.


Question: match eh_action { EHAction::None | EHAction::Cleanup(_) => return continue_unwind(exception_object, context), <del> EHAction::Catch(_) => return uw::_URC_HANDLER_FOUND, </del> <ins> EHAction::Catch(_) => { // EHABI requires the personality routine to update the // SP value in the barrier cache of the exception object. (*exception_object).private[5] = uw::_Unwind_GetGR(context, uw::UNWIND_SP_REG); return uw::_URC_HANDLER_FOUND; } </ins> EHAction::Terminate => return uw::_URC_FAILURE, } } else {

When I tested 1.40.0-beta.5 on , never completed on . When I run that test on arm directly, I get: The same happens when I use official builds of Rust 1.40-beta and 1.41-nightly, so it's not just a problem with Fedora's build of rustc or LLVM. This test didn't exist before , but running 1.39 on the current test just fails even earlier, as expected, "entered unreachable code: catch_unwind should not have caught foreign exception." I tried compiling the C++ part with GCC 9.2.1 and Clang 9.0.0, both with the same result. That's using libstdc++ either way though, because we don't have LLVM's libc++ available. cc
cc
PS: while I initially saw this on Fedora rawhide, my followup testing has been on stable Fedora 31.
That is very strange. And this behavior only occurs on ARM? I'm tempted to say that this is a bug in GCC's unwinder (in libgcc). Can you try this C++-only code to see if it has the same issue? a.cpp b.cpp This should print the message once and then fail with an uncaught exception.
Yes, the other arches completed and passed that test. Needs for , but then it works:
I tried stable 1.39 again commenting out the call to , then gets stuck in the same "caught foreign exception in catch" loop on the C++ side. In fact, this happens on every compiler I tried back to 1.13, which is the earliest I could get working at all! So at least it's not a new problem. Maybe we're generating bad unwind data, or maybe my libgcc has a bug in handling foreign exceptions, I don't know...
I think this might be a bug in the way the personality routine in libstdc++ (libsupc++ actually) handles foreign exceptions on ARM. Can you try using libc++ instead of libstdc++? Just change the linker args for rustc from to .
Oh, I found that Fedora does have libc++ packaged, and . But when I tried to use it simply as you indicate, foreign exceptions don't seem to be caught at all, in either direction.


Question: match eh_action { EHAction::None | EHAction::Cleanup(_) => return continue_unwind(exception_object, context), <del> EHAction::Catch(_) => return uw::_URC_HANDLER_FOUND, </del> <ins> EHAction::Catch(_) => { // EHABI requires the personality routine to update the // SP value in the barrier cache of the exception object. (*exception_object).private[5] = uw::_Unwind_GetGR(context, uw::UNWIND_SP_REG); return uw::_URC_HANDLER_FOUND; } </ins> EHAction::Terminate => return uw::_URC_FAILURE, } } else {

I see the binary still gets linked implicitly though, I think because adds it to std. I'll try to get a full build of rustc with just libc++ instead.
It's fine to link to , since that contains the libunwind implementation. The actual C++ personality functions are in libstd++/libc++abi. Can you post the test output with libc++?
Maybe this is obvious, but I have to compile the C++ part with clang++, not g++, or it gets "undefined reference to ". I wasn't sure whether to also use , but either way the C++ exception is not caught by Rust: So I commented out again to just try :
you may need to explicitly link libcxxabi depending on how libcxx was built. That should fix undefined reference error.
I did use -- do you mean more than that? If anyone else is interested in arm-linux, it would be great to get more hands on this, because that target is not a high priority for me. I will probably disable this test for arm in Fedora in the meantime.
I managed to reproduce this on Arch Linux with , so it's definitely not a Fedora-only issue.
no, that should be fine. Guess passing to the Clang (supported since 9.0.0) doesn't help either?
The link error was only when using g++ to compile That much was ok with clang++. I just tried adding to the clang command too, but got "argument unused during compilation".
I'm hitting this on Debian too. Running by itself does result in infinite-loop printing however the rust test suite is actually running . Directly running this however exits immediately, so I don't know why the test is hanging. I'll see if I can grab the environment from next time.
Ah nvmd, I just had to wrap the thing in single-quotes to reproduce the loop, the output of "pstree" is misleading.
Since this test is new in 1.40 I'll just for the time being in Debian.
Should be fixed by


Question: if let Some(path) = env::var_os("PATH") { new_path.extend(env::split_paths(&path)); } <ins> if sess.target.target.options.is_like_msvc { new_path.extend(msvc::host_dll_path()); } </ins> env::join_paths(new_path).unwrap() }

On nightly (and beta I believe) the compiler will currently fail when cross compiling from x86_64 to x86 (after ensuring the standard library is in the right location) with the message: I believe this is a regression from and , which were backported, so I believe this is a stable regression. That being said I doubt anyone other than Cargo CI is doing this, so it may not be that big. I also believe that is working on a patch, but this should help track this issue.
I have been doing this with ring and ring-based projects for many months.


Question: llvm::LLVMRustInstallFatalErrorHandler(); <ins> fn llvm_arg_to_arg_name(full_arg: &str) -> &str { full_arg.trim().split(|c: char| { c == '=' || c.is_whitespace() }).next().unwrap_or("") } let user_specified_args: FxHashSet<_> = sess .opts .cg .llvm_args .iter() .map(|s| llvm_arg_to_arg_name(s)) .filter(|s| s.len() > 0) .collect(); </ins> { <del> let mut add = |arg: &str| { let s = CString::new(arg).unwrap(); llvm_args.push(s.as_ptr()); llvm_c_strs.push(s); </del> <ins> // This adds the given argument to LLVM. Unless `force` is true // user specified arguments are *not* overridden. let mut add = |arg: &str, force: bool| { if force || !user_specified_args.contains(llvm_arg_to_arg_name(arg)) { let s = CString::new(arg).unwrap(); llvm_args.push(s.as_ptr()); llvm_c_strs.push(s); } </ins> }; <del> add("rustc"); // fake program name if sess.time_llvm_passes() { add("-time-passes"); } if sess.print_llvm_passes() { add("-debug-pass=Structure"); } if sess.opts.debugging_opts.disable_instrumentation_preinliner { add("-disable-preinline"); } </del> <ins> add("rustc", true); // fake program name if sess.time_llvm_passes() { add("-time-passes", false); } if sess.print_llvm_passes() { add("-debug-pass=Structure", false); } </ins> if sess.opts.debugging_opts.generate_arange_section { <del> add("-generate-arange-section"); </del> <ins> add("-generate-arange-section", false); </ins> } if get_major_version() >= 8 { match sess.opts.debugging_opts.merge_functions

LLVM's MergeFunctions introduces aliases which can trigger a bug in macOS's linker when compiling with ThinLTO: For this reason Firefox has to be built with a patched version of when compiling with xLTO. Since the bug in question is pretty nasty (the above example shows a program just returning a different value with no indication that anything is wrong), we should probably try to not trigger it. Right now, however, it seems that one cannot even turn the MergeFunctions pass off in stable Rust. (I wonder if the pass should even be disabled by default on macOS?) cc & (this seems related to )
Is it a mergefunc bug or a ThinLTO bug? Can it be triggered without ThinLTO? If not, I would rather not blindly disable it on macOS, at least not when ThinLTO isn't enabled.
It's not a bug in mergefunc. It might not even be a bug in ThinLTO. It's just that mergefunc is the only thing in that generates symbol aliases in LLVM IR, and these are what can lead to "miscompilations" when using the macOS linker.
Has the ld64 bug been reported somewhere?
We could use to prevent the pass from emitting aliases on macOS, AFAIK.
This is already supported via either or in the target spec.
Do you mean that the test case also fails with enabled, or that we already have a knob to disable them?
Answering my own question, we already have a knob for that.
Which was because .
As and point to there is the unstable option which I've only tested on nightly. I guess there could be a stabilized option, but maybe what you really want to do is to patch the x8664 macos target definition (I believe this is the correct one: ).
Yes, I've been told that it has been reported to Apple. On nightly, one can already control the mergefunc pass. On stable, however, one is stuck with the default behavior. That's what this issue is mostly about.
just want to double-check my understanding: I would have thought one could use the options and to override the set of passes, even on the stable channel. Am I incorrect about this? (If I am correct, I nonetheless will admit that this is an ugly (and very fragile) method to opt out of the MergeFunctions pass)
I think that is correct, yes.


Question: llvm::LLVMRustInstallFatalErrorHandler(); <ins> fn llvm_arg_to_arg_name(full_arg: &str) -> &str { full_arg.trim().split(|c: char| { c == '=' || c.is_whitespace() }).next().unwrap_or("") } let user_specified_args: FxHashSet<_> = sess .opts .cg .llvm_args .iter() .map(|s| llvm_arg_to_arg_name(s)) .filter(|s| s.len() > 0) .collect(); </ins> { <del> let mut add = |arg: &str| { let s = CString::new(arg).unwrap(); llvm_args.push(s.as_ptr()); llvm_c_strs.push(s); </del> <ins> // This adds the given argument to LLVM. Unless `force` is true // user specified arguments are *not* overridden. let mut add = |arg: &str, force: bool| { if force || !user_specified_args.contains(llvm_arg_to_arg_name(arg)) { let s = CString::new(arg).unwrap(); llvm_args.push(s.as_ptr()); llvm_c_strs.push(s); } </ins> }; <del> add("rustc"); // fake program name if sess.time_llvm_passes() { add("-time-passes"); } if sess.print_llvm_passes() { add("-debug-pass=Structure"); } if sess.opts.debugging_opts.disable_instrumentation_preinliner { add("-disable-preinline"); } </del> <ins> add("rustc", true); // fake program name if sess.time_llvm_passes() { add("-time-passes", false); } if sess.print_llvm_passes() { add("-debug-pass=Structure", false); } </ins> if sess.opts.debugging_opts.generate_arange_section { <del> add("-generate-arange-section"); </del> <ins> add("-generate-arange-section", false); </ins> } if get_major_version() >= 8 { match sess.opts.debugging_opts.merge_functions

It would be rather hard, however, to re-create the set of passes meaningfully, I suspect. Even the compiler delegates this to methods within LLVM, iirc.
I think using might work on stable.
So did that help,
Unfortunately not. Specifying this gives me:


Question: #![feature(iter_advance_by)] #![feature(slice_group_by)] #![feature(slice_partition_dedup)] <del> #![feature(vec_spare_capacity)] </del> #![feature(string_remove_matches)] #![feature(const_btree_new)] #![feature(const_default_impls)]

The feature gate for the issue is . Tracking issues are used to record the overall progress of implementation. They are also uses as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label. [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) [stabilization-guide]: https://rustc-dev- [doc-guide]: https://rustc-dev- Initial implementation ()
FWIW, here is a full-featured API provided by an external crate:
I wonder how this API relates to . It would be great if there was some safe API that wrapped around the use of to access a 's spare capacity, then updated based on the s .
Maybe we should follow that example and generalize to return ?
has implemented that, albeit as a private function. Sounds like a good idea to me.
Since exists now I think is redundant.
That's not actually true due to pointer invalidation, see and
I think it would be better to have this feature sooner rather than later. I'm starting to notice instances where people are doing things that are probably or definitely UB because they want this functionality. So I think this API falls squarely into the standard library's mission to provide pre-built and correct implementations of things that are subtle or difficult to get right.   (originally posted on but per Ralf's comments there, it is probably better to have this method for the above use cases)
I agree. I've been using this in my code and found it to be very useful. Even though is more general, I've never had a need for it and I feel that is useful on its own. The API being stabilized is: merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [x] [x] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!