Question: for possible_ancestor in min_cap_list.iter_mut() { match determine_place_ancestry_relation(&place, &possible_ancestor.place) { // current place is descendant of possible_ancestor <del> PlaceAncestryRelation::Descendant => { </del> <ins> PlaceAncestryRelation::Descendant | PlaceAncestryRelation::SamePlace => { </ins> ancestor_found = true; let backup_path_expr_id = possible_ancestor.info.path_expr_id;

Happy to review your PR
I'm not sure about region code that much but regionchk uses the regions created: I think at one point mentioned getting rid of the region field entirely in UpvarBorrow, but since it wasn't required the discussion didn't proceed. Also it's more like this is a bug of the capture analysis than the sorting. We should never have two same places going into min capture in the list.
I was thinking about erasing the region from s (i.e. the key of captureinformation). But it turns out that's used later to create upvar tuple... So I switched captureinformation from HashMap to a linear vec looked up with custom eq fn instead.


Question: # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. <del> 2017-03-02 </del> <ins> 2017-03-04 </ins>

This effectively means you can't compile for these targets.
This may have been caused by the i128 PR ( ). No LLVM assertion is raised if I compile with , which removes the i128 stuff. We could try to fix this or we could cfg away the i128 stuff for the nvptx targets in the meantine. The LLVM assertions render the NVPTX backend unusable in the nightlies. cc Have you seen any LLVM assertion like the ones above while working on implementing i128? cc cfg?
no, I can't remember seeing such an assertion. It seems to be in PTX related code. but its very likely that i128 broke some of the non tier1 platforms. You can only tell whether they break once they actually do :/ Can you try to generate a minimum reproducible example? Then we might know more...
Seems like the msp430 target broke too: with Using works fine. cc
Examples
msp430 EABI doesn't specify how to return 128 bit values, and LLVM does not support them on msp430, so I don't see an easy fix for this.
These are tier 3 platforms, so basically anything goes IMO in terms of language guarantees. If they don't support i128 at a fundamental level then it seems like if we want them to compile we'll have to cfg out support.
I'm trying to understand this better: If the ABI does not specify how 128-bit values are passed/returned, does that mean that the architecture doesn't support 128-bit values at the fundamental level?Do all the ABIs of the all the other platform 2 targets (x86, ARM, MIPS, PowerPC, SystemZ) specify how 128-bit values are returned?(What about wasm and Do those even have an ABI? How does the 128-bit stuff even works there?) I'm wondering if we should: Add a field to target specifications. For targets that don't support i128 at the fundamental level.Or, maybe add Cargo feature to to cfg away the i128 stuff.Or unilateraly cfg away i128 in core for nvptx and msp430. I personally don't like either option. To me this seems like a limitation in what LLVM can do today but that can be fixed in the future.


Question: # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. <del> 2017-03-02 </del> <ins> 2017-03-04 </ins>

Also, if we had pure MIR rlibs this wouldn't be a problem at all because the i128 stuff would never be passed to LLVM if it wasn't being used by the final application. To sum it up, I'm not sure what to do here ...
Right now on MSP430 values from the functions are returned using 4 16bit registers r12-r15. So in total you can return only 64 bits of data. There is an exception though, for returning large structs, the data is placed on the stack and reference is placed in the registers. So I guess it will be possible to bodge some hack that will treat i128 like a struct, but I don't know if anyone tried to implement 128 bit values on 16bit cpu, so it will be a new territory and potentially a lot of work for a feature that may not be useful at all on a small MCU.
yeah, but if LLVM can generate code for a function that returns then it should be able to use the same trick to return an . It's just that noboby has taught it how to do that. (i128 ops are totally different though but at least LLVM should emit intrinsics instead of raising assertions) How about on 8-bit AVR?
AFAIK, if Rust code calls Rust code, the ABI is totally irrelevant. We can do whatever we want. However, it starts getting a problem once we start talking to non Rust places, e.g. for FFI, or when LLVM emits a call to i128 intrinsics. For FFI we might want to end up forbidding fn's and structs that have i128 for targets where i128 is not specified by the convention or buggy in LLVM. With intrinsics, there has been major pain on Windows with because LLVM assumed a different ABI than what Rust provided with . It was "fixed" by introducing the "unadjusted" ABI, and it might work for nvptx64/msp430 as well, but it can just as well still cause an assertion failure. Real need for is only for platforms that want to cryptographic libraries, or maybe even std, as those two places might want to use . The higher stages of the compiler itself require i128 support as well, so if your platform wants to be a host platform for rustc, you'll need to support i128.


Question: # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. <del> 2017-03-02 </del> <ins> 2017-03-04 </ins>

I'm okay with any of the three options (flag in , feature for , only setting it for those two platforms) for these platforms.
No. No. Namely the x64 windows ABI is kinda fuzzy about how i128 values are handled so carefully reading it we arrived at a conclusion that they ought to be handled the same way as regular 16-byte structs on 64 bit window platforms. A target cannot not support i128 at a fundamental level the same way a target cannot not support writing turing complete software. IMO what we should do here is to fudge the ABIs somewhat to take and return arguments via pointers (or the same way would be handled) on these targets. C ABI will be more complex; as already said there will always be at least one user of the C ABI with i128 arguments and stuff – LLVM with their intrinsics. The question here is how does LLVM lower to the intrinsics on these targets. If the backend does not lower and asserts for whatever reason, the targets have what’s essentially a broken backend implementation. Which seems to be broken for at least NVPTX () in exactly the place where I’d expect it to be broken if it was broken: That being said, since the C compilers do not support i128 for those targets, the actual interoperation does not matter whatsoever. All that’s really needs to be fixed is LLVM’s lowering of instructions to intrinsics using whatever ABI that works, even if its passing in arguments and taking return value via pointers. I, myself, am very strongly against splitting the language feature sets depending on the target.
How do we break the stalemate? If we submitted changes upstream for each of the smaller targets w/o support for i128 (providing indirection like large structs) it seems like it would meet resistance. As says, it's likely not considered useful since there's many targets without any native registers or support for such large values. But we also also have reluctance to limit this type to only appropriate targets. Does the "vision for 2017 cycle" provide any guidance? Does "provide a more seamless FFI story" help push us in one direction or the other?
regardless whether useful or not, we do need to support i128 on all targets, otherwise people will start using libraries that provide it across platforms.


Question: # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. <del> 2017-03-02 </del> <ins> 2017-03-04 </ins>

Even if it needs to be "virtualized" in some way, and not wholly put into registers. In the worst case we'd have to provide some translation before passing things to LLVM, but it will affect things like alignment and generally looks like an ugly workaround. About FFI, I guess we can't really provide any FFI for i128 on targets where there is no C support for it, as generally the calling conventions only specify things that are part of C.
None of the targets Rust supports have native support for 128-bit integers, other than the fact that some can implement unchecked division and multiplication involving 128-bit integer operand with a single insn. Why? All that needs to be done here is to have the backends fixed. LLVM is supposed to be agnostic over bitwidth of integer, however useful or not somebody on the internet perceives such functionality to be. In other words, its a backend bug. So, its probably pretty clear that all it takes is to write a patch to fix bugs in these backends wrt operations on large values. I have no knowledge of these targets, am not familiar with the backends and haven’t the hardware to test any fixes on, so these patches will have to be written by somebody else. Late answer, but I’ve noticed this only now. This observation is wrong in multiple places. Firstly, (a.k.a. returning via pointer) is not a hack. Neither is it an exception. That’s what pretty much every single ABI¹ out there does for values that do not fit into register(s). It is most likely true that MSP430 ABI does not specify what to do with PODs this large, so it falls on us to pick whatever. ¹: For a less obscure example, x64 ABI used by code targetting Windows mandates to be used for any non-vector values over 64 bit in size, even though they could be fit it into registers. SysV ABI starts returning stuff via after some size threshold as well.
The MSP430 ABI specifies that aggregates larger than 32 bits are passed and returned via pointer. The backend just doesn't implement sret correctly yet (and in fact is implemented targeting an old and outdated ABI in any case). I'm working on fixing this in LLVM.


Question: # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. <del> 2017-03-02 </del> <ins> 2017-03-04 </ins>

I'd bet that similar problems explain the NVPTX problems but I know nothing about that platform so I can't say that for sure.
I also agree that fixing backend is the right thing to do. I just think that it is not that easy as you say it is. MSP430 is the only 16bit architecture in LLVM, and this creates some trouble by itself. Good to know that someone is working on this.
does that LLVM patch really fix NVPTX as well?
No, it doesn't. this should be reopened for NVPTX.
BTW, thanks to for fixing this in LLVM upstream.
Triage: MSP430 has been fixed. No change in the NVPTX backend.
What needs to be done to get NVPTX working again?
You can see the patch I did for the MSP430 above - if it's the same problem you basically just have to add sret (structure return) support to the LLVM backend. I don't know anything about NVPTX but I'd bet it's pretty much the same procedure as what I did for the MSP.
Note that you can use the NVPTX backend today with the nightly compiler if you use a fork of the libcore crate that doesn't include 128 bit integers. Instructions .
I have some progress on the issue. First, I tried a hacky workaround with replacing with in arguments and return values with a custom FunctionPass. Can be transformed to: And compiled to PTX with vanilla LLVM (): Then, I made less hacky workaround patching LLVM NVPTX backend so it became possible to compile the code with without additional passes. Is compiled with patched to pretty much valid and working PTX assembly ;) But another related problems appears. When instead of: I write: I receive an error: And similar error when I try to compile : Does anybody have any suggestions about the problems? Looks like PTX doesn't have an instructions for the functions, and LLVM can't expand them.
Looks like the expansion from i128 to i64 is going OK but the i64 sdiv/mulo instructions aren't properly implemented. Not sure why that might be... it kind of looks like it's trying to assign the address of a library call and that's not working. Possibly the way you implemented the i128 expansion prevented a subsequent i64 expansion from running but I can't tell without seeing the code.


Question: # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. <del> 2017-03-02 </del> <ins> 2017-03-04 </ins>

Run llc with -print-before-all and/or -print-machineinstrs to see where things diverge from what you expect. Look up in your platform ABI what the right action to take for 64-bit divides actually is. Post a link to your changes and someone may be able to take a look at them and see the problem.
Traditionally, in LLVM, is implemented by the library. However, its disabled on most platforms. Not sure why, but is written in C so they probably only can support i128 on platforms where they also provide C support, and clang's C support for i128 is right now very limited. Rust however the function, inside the crate (that is a wrapper for compiler-rt). There are good chances it works already!
It has pretty expected output before and after each pass. I think more interesting would be output with , but I don't really understand it. of the next commands: I tried to make changes over LLVM as minimal as possible: . I'm quite confused about and . Should they be compiled for target or host? If we can build at least for NVPTX, then can we just link against it? It still require some more changes for LLVM to be able to threat libcalls as normal calls. But then, all we would need is to link against . This blocked by but might be solved with my experimental .
For the target. At least its that way on other platforms. What is LLVM doing on 32 bit NVPTX when it encounters a 64 bit operation? On normal targets, this is one of the places compiler-rt gets used. Or idk, to cast a float to an int and back.
by the way, I didn't congratulate you yet for your progress. Really great work, loving it!
I'd like to see this move forward, so I'll summarize the above. Please correct me if I'm wrong: This issue was fixed for the MSP430 backend by submitting a patch to LLVM. worked on a patch to do the same for NVPTX, but it was not submitted to LLVM. I imagine that since that was a year ago, the patch will need some work to bring it up to date. Is this problem still happening with more recent builds? Perhaps it's been fixed by upstream in the meantime.


Question: # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. <del> 2017-03-02 </del> <ins> 2017-03-04 </ins>

If it is still a problem, what would have to be done to fix it?
Well, my patch related to landed in LLVM about year ago. Now we can compile simple examples without any problems: with which produces the PTX assembly: And as for me, the issue can be closed. I was able to compile a kernel from  with latest nightly. So the hack with custom is obsolete now.


Question: Ok(()) } } <ins> /// Returns the maximum size of return values to be passed by value in the Rust ABI. /// /// Return values beyond this size will use an implicit out-pointer instead. pub fn max_ret_by_val<C: HasTargetSpec + HasDataLayout>(spec: &C) -> Size { match spec.target_spec().arch.as_str() { // System-V will pass return values up to 128 bits in RAX/RDX. "x86_64" => Size::from_bits(128), _ => spec.data_layout().pointer_size, } } </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: Ok(()) } } <ins> /// Returns the maximum size of return values to be passed by value in the Rust ABI. /// /// Return values beyond this size will use an implicit out-pointer instead. pub fn max_ret_by_val<C: HasTargetSpec + HasDataLayout>(spec: &C) -> Size { match spec.target_spec().arch.as_str() { // System-V will pass return values up to 128 bits in RAX/RDX. "x86_64" => Size::from_bits(128), _ => spec.data_layout().pointer_size, } } </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: }); output.extend(items); <del> // Also add the destructor let dg_type = glue::get_drop_glue_type(scx.tcx(), trait_ref.self_ty()); output.push(TransItem::DropGlue(DropGlueKind::Ty(dg_type))); </del> } _ => { /* */ } } } <ins> // Also add the destructor let dg_type = glue::get_drop_glue_type(scx.tcx(), impl_ty); if glue::type_needs_drop(scx.tcx(), dg_type) { output.push(TransItem::DropGlue(DropGlueKind::Ty(dg_type))); } </ins> } }

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: }); output.extend(items); <del> // Also add the destructor let dg_type = glue::get_drop_glue_type(scx.tcx(), trait_ref.self_ty()); output.push(TransItem::DropGlue(DropGlueKind::Ty(dg_type))); </del> } _ => { /* */ } } } <ins> // Also add the destructor let dg_type = glue::get_drop_glue_type(scx.tcx(), impl_ty); if glue::type_needs_drop(scx.tcx(), dg_type) { output.push(TransItem::DropGlue(DropGlueKind::Ty(dg_type))); } </ins> } }

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: MergeFunctions::Disabled | MergeFunctions::Trampolines => {} MergeFunctions::Aliases => { <del> add("-mergefunc-use-aliases"); </del> <ins> add("-mergefunc-use-aliases", false); </ins> } } } if sess.target.target.target_os == "emscripten" && sess.panic_strategy() == PanicStrategy::Unwind { <del> add("-enable-emscripten-cxx-exceptions"); </del> <ins> add("-enable-emscripten-cxx-exceptions", false); </ins> } // HACK(eddyb) LLVM inserts `llvm.assume` calls to preserve align attributes // during inlining. Unfortunately these may block other optimizations. <del> add("-preserve-alignment-assumptions-during-inlining=false"); </del> <ins> add("-preserve-alignment-assumptions-during-inlining=false", false); </ins> for arg in &sess.opts.cg.llvm_args { <del> add(&(*arg)); </del> <ins> add(&(*arg), true); </ins> } }

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: MergeFunctions::Disabled | MergeFunctions::Trampolines => {} MergeFunctions::Aliases => { <del> add("-mergefunc-use-aliases"); </del> <ins> add("-mergefunc-use-aliases", false); </ins> } } } if sess.target.target.target_os == "emscripten" && sess.panic_strategy() == PanicStrategy::Unwind { <del> add("-enable-emscripten-cxx-exceptions"); </del> <ins> add("-enable-emscripten-cxx-exceptions", false); </ins> } // HACK(eddyb) LLVM inserts `llvm.assume` calls to preserve align attributes // during inlining. Unfortunately these may block other optimizations. <del> add("-preserve-alignment-assumptions-during-inlining=false"); </del> <ins> add("-preserve-alignment-assumptions-during-inlining=false", false); </ins> for arg in &sess.opts.cg.llvm_args { <del> add(&(*arg)); </del> <ins> add(&(*arg), true); </ins> } }

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: <ins> use rustc_middle::ty::TyCtxt; use rustc_middle::ty::Visibility; use crate::clean; use crate::clean::Item; use crate::core::DocContext; use crate::fold::{strip_item, DocFolder}; use crate::passes::Pass; pub(crate) const STRIP_ALIASED_NON_LOCAL: Pass = Pass { name: "strip-aliased-non-local", run: strip_aliased_non_local, description: "strips all non-local private aliased items from the output", }; fn strip_aliased_non_local(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { let mut stripper = AliasedNonLocalStripper { tcx: cx.tcx }; stripper.fold_crate(krate) } struct AliasedNonLocalStripper<'tcx> { tcx: TyCtxt<'tcx>, } impl<'tcx> DocFolder for AliasedNonLocalStripper<'tcx> { fn fold_item(&mut self, i: Item) -> Option<Item> { Some(match *i.kind { clean::TypeAliasItem(..) => { let mut stripper = NonLocalStripper { tcx: self.tcx }; // don't call `fold_item` as that could strip the type-alias it-self // which we don't want to strip out stripper.fold_item_recur(i) } _ => self.fold_item_recur(i), }) } } struct NonLocalStripper<'tcx> { tcx: TyCtxt<'tcx>, } impl<'tcx> DocFolder for NonLocalStripper<'tcx> { fn fold_item(&mut self, i: Item) -> Option<Item> { // If not local, we want to respect the original visibility of // the field and not the one given by the user for the currrent crate. // // FIXME(#125009): Not-local should probably consider same Cargo workspace if !i.def_id().map_or(true, |did| did.is_local()) { if i.visibility(self.tcx) != Some(Visibility::Public) || i.is_doc_hidden() { return Some(strip_item(i)); } } Some(self.fold_item_recur(i)) } } </ins>

I tried this code: with and . I expected to see this happen: No internal fields of the should be displayed as users won't be able to use the fields, making their appearance confusing and useless. Instead, this happened: The internal fields of the are displayed ! Real impact as can be seen . : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
labels +T-rustdoc +A-rustdoc-ui -needs-triage claim
Dupe of and more discussion there


Question: <ins> use rustc_middle::ty::TyCtxt; use rustc_middle::ty::Visibility; use crate::clean; use crate::clean::Item; use crate::core::DocContext; use crate::fold::{strip_item, DocFolder}; use crate::passes::Pass; pub(crate) const STRIP_ALIASED_NON_LOCAL: Pass = Pass { name: "strip-aliased-non-local", run: strip_aliased_non_local, description: "strips all non-local private aliased items from the output", }; fn strip_aliased_non_local(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { let mut stripper = AliasedNonLocalStripper { tcx: cx.tcx }; stripper.fold_crate(krate) } struct AliasedNonLocalStripper<'tcx> { tcx: TyCtxt<'tcx>, } impl<'tcx> DocFolder for AliasedNonLocalStripper<'tcx> { fn fold_item(&mut self, i: Item) -> Option<Item> { Some(match *i.kind { clean::TypeAliasItem(..) => { let mut stripper = NonLocalStripper { tcx: self.tcx }; // don't call `fold_item` as that could strip the type-alias it-self // which we don't want to strip out stripper.fold_item_recur(i) } _ => self.fold_item_recur(i), }) } } struct NonLocalStripper<'tcx> { tcx: TyCtxt<'tcx>, } impl<'tcx> DocFolder for NonLocalStripper<'tcx> { fn fold_item(&mut self, i: Item) -> Option<Item> { // If not local, we want to respect the original visibility of // the field and not the one given by the user for the currrent crate. // // FIXME(#125009): Not-local should probably consider same Cargo workspace if !i.def_id().map_or(true, |did| did.is_local()) { if i.visibility(self.tcx) != Some(Visibility::Public) || i.is_doc_hidden() { return Some(strip_item(i)); } } Some(self.fold_item_recur(i)) } } </ins>

Using to document private types of the current workspace exposes external types private implementation details (in this case private fields). I would expect the expansion to limit itself to public fields. e.g. gives ! <details<summary<coderustc --version --verbose</code</summary<p</p</detailsr?
I suppose it's "ok" since you used the option. I'll add it to the next rustdoc team meeting agenda to be confirmed by the team.
Rendered output for anyone wondering: !
I'll summarize the exchange I had with Guillaume on matrix. First, the flag I'm talking about is the one you provide to . does not blindly pass the flag to but only for crates you own in your current workspace. That means that when documenting your workspace with . Private items, fields of your crates are shown contrary to your dependencies. Regarding design, it seems weird to me that aliased type expansion shows private implementation details of dependencies (e.g. for the given example). I would personally expect something like:


Question: pub fn install_ctrlc_handler() { #[cfg(not(target_family = "wasm"))] ctrlc::set_handler(move || { <del> // Indicate that we have been signaled to stop. If we were already signaled, exit // immediately. In our interpreter loop we try to consult this value often, but if for // whatever reason we don't get to that check or the cleanup we do upon finding that // this bool has become true takes a long time, the exit here will promptly exit the // process on the second Ctrl-C. if CTRL_C_RECEIVED.swap(true, Ordering::Relaxed) { std::process::exit(1); } </del> <ins> // Indicate that we have been signaled to stop, then give the rest of the compiler a bit of // time to check CTRL_C_RECEIVED and run its own shutdown logic, but after a short amount // of time exit the process. This sleep+exit ensures that even if nobody is checking // CTRL_C_RECEIVED, the compiler exits reasonably promptly. CTRL_C_RECEIVED.store(true, Ordering::Relaxed); std::thread::sleep(Duration::from_millis(100)); std::process::exit(1); </ins> }) .expect("Unable to install ctrlc handler"); }

Sometimes when things go really wrong the compiler emits a ton of error messages. This can actually take a while to render them all. And since somewhat recently, hitting Ctrl-C no longer interrupts that, I get a thousand error messages displayed after Ctrl-C. I suspect this may have to do with The Ctrl-C handler does nothing at all on the first Ctrl-C unless the compiler is in the middle of const-eval. Cc
Do you have a reproducer? I have not run into this myself. The implementation should also ensure that the compiler exits promptly if you hit ctrl+c again. Does it?
if stuff keeps going on ctrl+c, sometimes suspending the process (ctrl+z) and then killing the terminal does the trick somehow :sweat_smile:
Unfortunately no, I encountered this during some rustc hacking where I ended up getting well over 1k error messages in the standard library build and that turned out to be hard to cancel. I thought I had tried that, but I am not entirely sure.
Is it possible the shell is part of the problem? If, by the time you hit ctrl-c, it's working through a large amount of output it still has buffered then it might be awhile before you see a response.
It's possible, sure -- but usually it reacts to Ctrl-C immediately even when there's tons of output.
Have you tried reverting to check if that fixes it?
No. At the time I was busy getting a PR done and now I don't have a reproducing example any more.
only checks for ctrl-c during const eval, so if no const eval runs for an extended period of time, the ctrl-c will be silently ignored. This is not the only problem with that PR. It also caused , and shows the "compilation was interrupted" error after the prompt is already drawn by bash.
is there a good way to make rustc loop endlessly without ever touching const eval? maybe via the trait solver? :thinking: it would help for debugging this.
Yeah, just take any issue (none are anyway). I can reproduce this issue with for example: nightly-2024-03-26 (before ): Exits after a single ^C nightly-2024-03-27 (after ): Requires ^C^C to exit bjorn3's analysis checks out.
cool!


Question: pub fn install_ctrlc_handler() { #[cfg(not(target_family = "wasm"))] ctrlc::set_handler(move || { <del> // Indicate that we have been signaled to stop. If we were already signaled, exit // immediately. In our interpreter loop we try to consult this value often, but if for // whatever reason we don't get to that check or the cleanup we do upon finding that // this bool has become true takes a long time, the exit here will promptly exit the // process on the second Ctrl-C. if CTRL_C_RECEIVED.swap(true, Ordering::Relaxed) { std::process::exit(1); } </del> <ins> // Indicate that we have been signaled to stop, then give the rest of the compiler a bit of // time to check CTRL_C_RECEIVED and run its own shutdown logic, but after a short amount // of time exit the process. This sleep+exit ensures that even if nobody is checking // CTRL_C_RECEIVED, the compiler exits reasonably promptly. CTRL_C_RECEIVED.store(true, Ordering::Relaxed); std::thread::sleep(Duration::from_millis(100)); std::process::exit(1); </ins> }) .expect("Unable to install ctrlc handler"); }

I wasn't sure how much of the compiler's code flowed through const-eval, is why I asked.
Another case where this is observed: IMO we should revert or at least make the signal handler run after a short timeout.
I'll post a PR that adds a timeout later today, but by all means if you feel strongly just put up a PR. The initial handler here was just through the normal PR process, there's no reason to be more cautious on reverting or modifying it.


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

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: use std::c_str::ToCStr; use std::cast; <ins> use std::hashmap::{HashMap, HashSet}; </ins> use std::cmp; use std::io; use std::os::consts::{macos, freebsd, linux, android, win32};

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: <ins> error: macro-expanded `extern crate` items cannot shadow names passed with `--extern` --> $DIR/issue-109148.rs:6:9 | LL |         extern crate core as std; |         ^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | m!(); | ---- in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error </ins>

<!-- 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 --
claim
label +S-bug-has-mcve
I'm having trouble understanding this ICE. Could someone point me in the right direction? Thanks for your help!
release-assignment I'm finding this quite hard. For anyone else: I suspect is responsible.


Question: use syntax::source_map::Span; use super::{ <del> FnVal, GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, StackPopCleanup, </del> <ins> FnVal, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, StackPopCleanup, </ins> }; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

Follow-up to agreed to move to . Generally I propose that should not contain code that is only needed by CTFE. We have and in there are they need some very deep access to Miri engine internals, but at least those are separate modules. Also, has grown pretty messy, and it does not seem like the order of definitions in that file follows any principle. We could split the file into two similar to what I did with Miri: for implementing the machine trait and defining everything that is needed during CTFE execution, and for defining the setup functions and all the glue that connects CTFE with the rest of the compiler.


Question: self_ty: Ty<'tcx>, sig: ty::PolyGenSig<'tcx>, ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> { <del> debug_assert!(!self_ty.has_escaping_bound_vars()); </del> <ins> assert!(!self_ty.has_escaping_bound_vars()); </ins> let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty]); sig.map_bound(|sig| (trait_ref, sig.return_ty)) }

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> #[cfg(test)] mod bench; </del> <ins> #[cfg(test)] #[macro_use] mod bench; </ins> // FIXME(#14344) this shouldn't be necessary #[doc(hidden)]

the closure being passed into in BTreeMap and VecMap's benches has a trailing semi-colon making the return value , and thus making the entire operation a no-op. Removing the semi-colon causes lifetime conflict issues. CC
I have a branch that just gives up and replaces these with macros. This results in clearer and more concise code like . Confirmed produces sane results in benchmark output. Hope to submit something tomorrow.


Question: <ins> // Regression test for https://github.com/rust-lang/rust/issues/43134 // check-pass // compile-flags: --cap-lints allow type Foo<T: Clone> = Option<T>; fn main() {} </ins>

Test case: With rustc 1.20.0-nightly ( 2017-07-06), output when compiling with : correctly stops the dead code / unused type alias warning from being shown, but the trait bounds not enforced warning is shown anyway. Per and , this might be on purpose. I think this is the wrong decision. The point of is to allow Cargo to inhibit warnings in external dependencies. When building Servo it is not useful to spam the console with many warnings, future-proofing or not, about code that Servo has not direct control over. CC
Nominating for discussion. Not sure if compiler team or lang team is best, though, so tagging both...
From the lang team's point of view: definitely a bug.
Couple of bugs here: First off, we should not be ignoring the bounds in types. And sometimes they are needed. I'd like to fix this by not ignoring them, but I worry about the backcompat issues. Unknown risk there. Second, if we must warn, we should be emitting a regular lint that can be silenced. Plausibly, we should just remove the warning (eliminating the immediate problem), and prioritize trying to do a proper fix here.
Somewhat related to not ignoring bounds (but in the other direction): .
After some discussion in compiler team, decided to move this to a "future compatibility" lint, one that we will hopefully make more precise over time. Right now the check is not very good. At least this means you won't have to see it. We need some mentoring instructions though!
Some tips here:
triage: P-medium
I've hit this recently. It seems like it is possible to write code that requires exactly this bound. So it is quite bad that we cannot suppress this warning. Example code:
Agreed, this is poor. There just hasn't been a lot of energy to try and improve the situation.
Fixed in , probably by We should add a regression test for this particular case before we close this issue however, since I don't think the test in the PR detects a regression for the problem described in this issue. The problem in this issue is output on stderr, not that compilation fails ( exit code is 0 both with and without the fix in the PR). label E-needs-test


Question: fn parse_crate_mod(&mut self) -> Result<ast::Crate, ParserError> { let mut parser = AssertUnwindSafe(&mut self.parser); <del> match catch_unwind(move || parser.parse_crate_mod()) { Ok(Ok(k)) => Ok(k), Ok(Err(db)) => { </del> <ins> // rustfmt doesn't use `run_compiler` like other tools, so it must emit // any stashed diagnostics itself, otherwise the `DiagCtxt` will assert // when dropped. The final result here combines the parsing result and // the `emit_stashed_diagnostics` result. let parse_res = catch_unwind(move || parser.parse_crate_mod()); let stashed_res = self.parser.dcx().emit_stashed_diagnostics(); let err = Err(ParserError::ParsePanicError); match (parse_res, stashed_res) { (Ok(Ok(k)), None) => Ok(k), (Ok(Ok(_)), Some(_guar)) => err, (Ok(Err(db)), _) => { </ins> db.emit(); <del> Err(ParserError::ParseError) </del> <ins> err </ins> } <del> Err(_) => Err(ParserError::ParsePanicError), </del> <ins> (Err(_), _) => err, </ins> } } }

<!-- 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
I suspect this is related to cc
tests/ui/suggestions/unnamable-
Very likely. I'll take a look soon.
For the record: it was that caused this.


Question: use use_from_trait_xc::Trait::foo; //~^ ERROR `foo` is not directly importable <ins> use use_from_trait_xc::Trait::Assoc; //~^ ERROR `Assoc` is not directly importable use use_from_trait_xc::Trait::CONST; //~^ ERROR `CONST` is not directly importable </ins> use use_from_trait_xc::Foo::new; //~^ ERROR `new` is not directly importable <ins> use use_from_trait_xc::Foo::C; //~^ ERROR unresolved import `use_from_trait_xc::Foo::C` </ins> use use_from_trait_xc::Bar::new as bnew; //~^ ERROR `bnew` is not directly importable

with rustc 1.0.0-nightly ( 2015-03-01) (built 2015-03-01)
This is still an issue
Still an issue in 1.0.0.
This is still an issue in 1.3.0-nightly: $ rustc error: internal compiler error: unexpected panic thread 'rustc' panicked at 'assertion failed: <= ()', stack backtrace: 1: 0x7fd6c19bd5ee - sys::backtrace::write::h04a6ced565b26815Lqs 2: 0x7fd6c19c5214 - panicking::onpanic::h521f84b604e22dfel8w 3: 0x7fd6c198804e - rt::unwind::beginunwindinner::hd3dee614a0e1c16cZNw 4: 0x7fd6c1988d7c - rt::unwind::beginunwindfmt::ha4ce6704c81423045Mw 5: 0x7fd6c19c4dd6 - rustbeginunwind 6: 0x7fd6c1a15bb4 - panicking::panicfmt::he89ea3094b3178e919B 7: 0x7fd6c1a0f9dd - panicking::panic::h9e565ee21070221by8B 8: 0x7fd6c11f8271 - astconv::finishresolvingdeftoty::h03670159ac2fefe7aTv 9: 0x7fd6c11b6340 - astconv::asttytoty::hb2c49d2cf31c029bYUv 10: 0x7fd6c1189eed - check::closure::checkexprclosure::hbce85e7beaf0ebd52zl 11: 0x7fd6c11d360b - check::checkexprwithunifier::h16314096699859592584 12: 0x7fd6c11f998b - check::checkdeclinitializer::h491ede37e45bce9e84r 13:


Question: use use_from_trait_xc::Trait::foo; //~^ ERROR `foo` is not directly importable <ins> use use_from_trait_xc::Trait::Assoc; //~^ ERROR `Assoc` is not directly importable use use_from_trait_xc::Trait::CONST; //~^ ERROR `CONST` is not directly importable </ins> use use_from_trait_xc::Foo::new; //~^ ERROR `new` is not directly importable <ins> use use_from_trait_xc::Foo::C; //~^ ERROR unresolved import `use_from_trait_xc::Foo::C` </ins> use use_from_trait_xc::Bar::new as bnew; //~^ ERROR `bnew` is not directly importable

0x7fd6c11f9a4d - check::checkdecllocal::h1c782249285c9ae3m6r 14: 0x7fd6c11f9c79 - check::checkstmt::h48bf6ea3f412b86bf8r 15: 0x7fd6c11a91b3 - check::checkblockwithexpected::h072b2c4702c43b1cjcs 16: 0x7fd6c118bef4 - check::checkfn::h8218f9adb3734183iQn 17: 0x7fd6c11a35ca - check::checkbarefn::h3c567a2d1339f838RFn 18: 0x7fd6c11a1523 - check::checkitembody::h8e17e6521c30131ay6n 19: 0x7fd6c11a31e4 - check::checkitemtypes::h62e908b1d9f74b39oDn 20: 0x7fd6c12609b8 - checkcrate::h594ee0148d251222uZC 21: 0x7fd6c1f1dc69 - driver::phase3runanalysispasses::closure.


Question: use use_from_trait_xc::Trait::foo; //~^ ERROR `foo` is not directly importable <ins> use use_from_trait_xc::Trait::Assoc; //~^ ERROR `Assoc` is not directly importable use use_from_trait_xc::Trait::CONST; //~^ ERROR `CONST` is not directly importable </ins> use use_from_trait_xc::Foo::new; //~^ ERROR `new` is not directly importable <ins> use use_from_trait_xc::Foo::C; //~^ ERROR unresolved import `use_from_trait_xc::Foo::C` </ins> use use_from_trait_xc::Bar::new as bnew; //~^ ERROR `bnew` is not directly importable

22: 0x7fd6c1f1c633 - middle::ty::ctxt<'tcx::createandenter::h349256048753845929 23: 0x7fd6c1f17a17 - driver::phase3runanalysispasses::h15521018079403107052 24: 0x7fd6c1efa266 - driver::compileinput::hbf698b02349f7ce3Tba 25: 0x7fd6c1fd3ed3 - runcompiler::hd724b5fef3441688y7b 26: 0x7fd6c1fd18ae - boxed::F.FnBox<A::callbox::h6609070342514802751 27: 0x7fd6c1fd10f9 - rt::unwind::try::tryfn::h10774555836369096370 28: 0x7fd6c1a3ed48 - rusttryinner 29: 0x7fd6c1a3ed35 - rusttry 30: 0x7fd6c19b08a7 - rt::unwind::try::innertry::hb0d7a3eb324339ceSJw 31: 0x7fd6c1fd130b - boxed::F.FnBox<A::callbox::h18179817771297192954 32: 0x7fd6c19c3e71 - sys::thread::Thread::new::threadstart::hf8c7448e27294ed0PTv 33: 0x7fd6bb60f353 - startthread 34: 0x7fd6c161ebfc - _clone 35: 0x0 - <unknown
$ rustc --version rustc 1.3.0-nightly ( 2015-06-30)
This problem has gone away for me now. It may have been from mixing versions? It may have gone away after a .
It is still an issue on nightly according to the playpen:
You're right. I must have been in the wrong project.
I just ran into the same assertion (with both stable 1.1 and nightly 1.3), but with different code.


Question: use use_from_trait_xc::Trait::foo; //~^ ERROR `foo` is not directly importable <ins> use use_from_trait_xc::Trait::Assoc; //~^ ERROR `Assoc` is not directly importable use use_from_trait_xc::Trait::CONST; //~^ ERROR `CONST` is not directly importable </ins> use use_from_trait_xc::Foo::new; //~^ ERROR `new` is not directly importable <ins> use use_from_trait_xc::Foo::C; //~^ ERROR unresolved import `use_from_trait_xc::Foo::C` </ins> use use_from_trait_xc::Bar::new as bnew; //~^ ERROR `bnew` is not directly importable

Would it help if I try to create another minimal working example and post it here or a new bug report? This is my backtrace: didn't help.
Okay here it is: Unfortunately it has something to do with glium, so I guess this doesn't help much :/
May be related, not sure: (rustc 1.2.0 ( 2015-08-03))
minimized:


Question: pub fn run_silent(cmd: &mut Command) { let status = match cmd.status() { Ok(status) => status, <del> Err(e) => fail(&format!("failed to execute command: {}", e)), </del> <ins> Err(e) => fail(&format!("failed to execute command: {:?}nerror: {}", cmd, e)), </ins> }; if !status.success() { fail(&format!("command did not execute successfully: {:?}n

Rustbuild now prints which is very not helpful.
I've hit this one too: When there's a stale in Rust's root directory, bootstrap reads paths from there and tries to convert them into windows format using (which it, of course, can't find since we are not running in msys shell). The error message comes from in buildhelper (called from ).


Question: /// /// # Examples /// ``` <del> /// #![feature(div_duration)] </del> /// use std::time::Duration; /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); /// ``` <del> #[unstable(feature = "div_duration", issue = "63139")] </del> <ins> #[stable(feature = "div_duration", since = "CURRENT_RUSTC_VERSION")] </ins> #[must_use = "this returns the result of the operation,  without modifying the original"] #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn div_duration_f64(self, rhs: Duration) -> f64 { <del> self.as_secs_f64() / rhs.as_secs_f64() </del> <ins> let self_nanos = (self.secs as f64) * (NANOS_PER_SEC as f64) + (self.nanos.0 as f64); let rhs_nanos = (rhs.secs as f64) * (NANOS_PER_SEC as f64) + (rhs.nanos.0 as f64); self_nanos / rhs_nanos </ins> } /// Divide `Duration` by `Duration` and return `f32`. /// /// # Examples /// ``` <del> /// #![feature(div_duration)] </del> /// use std::time::Duration; /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` <del> #[unstable(feature = "div_duration", issue = "63139")] </del> <ins> #[stable(feature = "div_duration", since = "CURRENT_RUSTC_VERSION")] </ins> #[must_use = "this returns the result of the operation,  without modifying the original"] #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn div_duration_f32(self, rhs: Duration) -> f32 { <del> self.as_secs_f32() / rhs.as_secs_f32() </del> <ins> let self_nanos = (self.secs as f32) * (NANOS_PER_SEC as f32) + (self.nanos.0 as f32); let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.0 as f32); self_nanos / rhs_nanos </ins> } }

Rust PR: This feature adds the following methods to : -
Anything in particular holding up the stabilization here? The implementation is trivial and docs lgtm.
I would like to add methods that return an exact , but that can wait.
These methods are a little odd, but seem reasonable to me following the example given:
Given how straightforward these methods are, I don't think there's any problem stabilising them?
They're straightforward in implementation, but conceptually tricky at a glance. I think the docs will need some fleshing out before stabilizing but I don't have any other concerns if somebody wants to write a PR!
This needs more testing with various interesting values that could produce interesting floating point numbers, and should not be stabilized without such.
tests were in this PR


Question: <ins> // https://github.com/rust-lang/rust/issues/116796 struct X<const FN: fn() = { || {} }>; //~^ ERROR using function pointers as const generic parameters is forbidden fn main() {} </ins>

File: auto-reduced (treereduce-rust): original: Version information ` Command:
<!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details
really need to add auto-bisection to icemaker reports... Regression in nightly-2021-04-26 found 9 bors merge commits in the specified range commit[0] 2021-04-24: Auto merge of - davidhewitt:revert-, r=GuillaumeGomez commit[1] 2021-04-24: Auto merge of - RalfJung:const-fn-feature-flags, r=oli-obk commit[2] 2021-04-25: Auto merge of - jyn514:no-span, r=GuillaumeGomez commit[3] 2021-04-25: Auto merge of - CDirkx:rt, r=m-ou-se commit[4] 2021-04-25: Auto merge of - cuviper:array-method-dispatch, r=nikomatsakis,m-ou-se commit[5] 2021-04-25: Auto merge of - RalfJung:black-box, r=Mark-Simulacrum commit[6] 2021-04-25: Auto merge of - lcnr:const-generics-defaults-name-res, r=varkor commit[7] 2021-04-25: Auto merge of - RalfJung:miri, r=RalfJung commit[8] 2021-04-25: Auto merge of - jsha:ephemeral-collapse, r=GuillaumeGomez maybe ?
hm, with , this crashes like this:
Hmm, I'm confused by the result of the bisection, I expected it to find a relatively recent commit since the reproducer doesn't ICE on stable (1.73) (while it does ICE on beta and nightly):
Doesn't ICE if is enabled.
this feature fixing an ice instead of causing one, that's a first...
This errors cleanly since beta 1.76.


Question: use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::DefIdSet; use rustc_span::symbol::{kw, sym, Ident}; <del> use rustc_span::Symbol; </del> use rustc_span::{edit_distance, ExpnKind, FileName, MacroKind, Span}; <ins> use rustc_span::{Symbol, DUMMY_SP}; </ins> use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote; use rustc_trait_selection::traits::error_reporting::on_unimplemented::TypeErrCtxtExt as _;

<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed: param types with same index differ in name'', 'thread 'rustc' panicked at 'assertion failed: param types with same index differ in name'' File: --auto-reduced (treereduce-rust): original: Version information ` Command:
thanks for the stack trace for this class of ICEs, it's just the right thing that I need. Minimal:


Question: def.variant_descr(), self.tcx.def_path_str(def.did) ) <del> .span_label(span, "private field") </del> <ins> .span_label(span, label) </ins> .emit(); } }

In a recent PR I made a change to unify the wording of multiple privacy errors, but : used to be This one change needs to be reversed while keeping the rest.
Hi! Could I give this issue a shot?
I am sorry I forgot to claim the issue
No worries :-)


Question: let rty = ccx.tcx.node_id_to_type(id); let fcx = FnCtxt::new(&inh, ty::FnConverging(rty), e.id); let declty = fcx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty; <ins> fcx.require_type_is_sized(declty, e.span, traits::ConstSized); </ins> fcx.check_const_with_ty(sp, e, declty); }); }

This looks unintentional, and has been broken in all cases, until a few releases ago, AFAICT. Should this be covered by WF rules? cc Unsized constants cause an ICE, in both old trans and MIR trans: Unsized statics appear to work, but only in old trans: I believe this is possible because a constant DST lvalue in old trans is merely the fat pointer. It seems useful to allow an unsized , but IMO it should require a sized RHS instead, i.e.: And, of course, this should all go through the RFC process, to figure out all the finer details.
Should it be ? I don't think A needs to be an lvalue.
It makes more sense for constants, but I gave the example with because that's the only one that works today (although by accident).
Hmm? I mean the static is desugared into a const. works today.
The idea being that a static and a const reference both give access to one lvalue.
No, has different semantics: it allows an somewhere within and is guaranteed not to be duplicated.
Hmm? Both of these gives me a "error: cannot borrow a constant which contains interior mutability, create a static instead". This is what I'd suspect as the lvalue from the promoted has nothing to do with being a or a .
Let me rewrite my desugaring to account for that, oops.
Oh and my confusion really just stemmed from forgetting about the constants referring to statics rule. [Kind of a funny rule when works, but this is an orthogonal issue.]
I think in the meantime unsized statics should probably error, perhaps dependent on a crater run, though I doubt there's many people relying on said bug. It's much easier to relax restrictions than tighten them.
Will prepare a patch to turn this into an error, hopefully nobody has been abusing it.


Question: <del> // no-prefer-dynamic </del> #![feature(unsized_tuple_coercion)] static mut DROP_RAN: bool = false;

Right now on our bots we're basically in a state where if valgrind rpass tests are compiled dynamically they will all fail, but when compiled statically they will pass. I'm not really sure what's going on unfortunately, but this is either a bug in valgrind or a bug with us, and we should know precisely what it is to ensure something more sinister isn't lurking. Some links: - first pass at linking tests statically, fixed - another pass at linking all tests statically
All the failures seem to be within platform’s dynamic loader. Here’s a few things to try: updating kernel+glibc to the most recent versions (4.4-ish and 2.23-ish, respectively) help? downgrading kernel+glibc to some older version help? non-linux/non-glibc work correctly?
Any news/changes on this one ?


Question: names } <ins> /// Returns a scope, plus `true` if that's a type scope for "class" methods, /// otherwise `false` for plain namespace scopes. </ins> fn get_containing_scope<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, <del> ) -> &'ll DIScope { </del> <ins> ) -> (&'ll DIScope, bool) { </ins> // First, let's see if this is a method within an inherent impl. Because // if yes, we want to make the result subroutine DIE a child of the // subroutine's self-type. <del> let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| { </del> <ins> if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) { </ins> // If the method does *not* belong to a trait, proceed if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(

If you combine LTO, anything that uses alloc and debug compilation mode, the compiler fails. The minimum example to reproduce is this : With this : To reproduce, run (or just use ): You should see this error: The above error does not reproduce for other compiler versions or options, all of the below work: I found reporting something similar, but for them is throwing the error, so I opened a new issue instead. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Initial reduction for :
Filed
In , dblaikie suggests that ought to separate the type-method declaration from the function definition, and I think I have that working. It passes the reproducer here, at least... claim


Question: names } <ins> /// Returns a scope, plus `true` if that's a type scope for "class" methods, /// otherwise `false` for plain namespace scopes. </ins> fn get_containing_scope<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, <del> ) -> &'ll DIScope { </del> <ins> ) -> (&'ll DIScope, bool) { </ins> // First, let's see if this is a method within an inherent impl. Because // if yes, we want to make the result subroutine DIE a child of the // subroutine's self-type. <del> let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| { </del> <ins> if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) { </ins> // If the method does *not* belong to a trait, proceed if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(

<!-- Thank you for filing a regression report! A regression is something that changed between versions of Rust but was not supposed to. Please provide a short summary of the regression, along with any information you feel is relevant to replicate it. --Since nightly release , we've had build failures for () with message when lto is enabled. If I disable LTO, the build succeeds and the test passes. There are many similar tests which do currently build and run successfully with this version, it is only one specific test we have which is causing the issue. You can reproduce the issue if you build the test in release mode: I haven't been able to work out what actually causes this, and it seems to require a reasonable amount of code before the issue gets triggered. <!-- Provide the most recent version this worked on, for example: It most recently worked on: Rust 1.47 --It most recently worked on: Rust nightly 2023-03-23 <!-- Provide the version you are using that has the regression. --: The error message isn't particularly helpful here, but here is the full output from our github action: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
here probably more info on how to reproduce could help. If I read the , the test alone compiles but it fails when enabling the flag, thus the label. label E-needs-mcve
WG-prioritization assigning priority (). label -I-prioritize +P-medium
Probably related to the LLVM upgrade, but I was unable to reduce this to a pure LLVM reproducer.
We just got this error building Firefox on Fedora 38, with Rust 1.69.0 and LLVM 16.0.1:
See /
I'll try a build with that patch. One thing to note though, regarding: The Firefox build got this message on aarch64, ppc64le, and x86_64. (Only s390x succeeded.)
D147620 worked locally for me, building LLVM 16 with that patch and then Firefox built fine. But it looks like that review is not settled yet.


Question: names } <ins> /// Returns a scope, plus `true` if that's a type scope for "class" methods, /// otherwise `false` for plain namespace scopes. </ins> fn get_containing_scope<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, <del> ) -> &'ll DIScope { </del> <ins> ) -> (&'ll DIScope, bool) { </ins> // First, let's see if this is a method within an inherent impl. Because // if yes, we want to make the result subroutine DIE a child of the // subroutine's self-type. <del> let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| { </del> <ins> if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) { </ins> // If the method does *not* belong to a trait, proceed if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(

Whether the ultimate fix is in LLVM or rustc, I hope we can get that into beta for the 1.70.0 release.
I have a patch for rustc that passes the test case in -- I'll try with Firefox later today. claim


Question: name_was_remapped: bool, unmapped_path: FileName, mut src: String, <del> start_pos: BytePos) -> SourceFile { </del> <ins> start_pos: BytePos) -> Result<SourceFile, OffsetOverflowError> { </ins> remove_bom(&mut src); let src_hash = {

I know that having huge literal in source is a bad idea, but it should not cause ICE :( It looks like something overflowed. Version: Command, output and backtrace: Here is the generator of the source:
cc
Took a quick look. We certainly have a restriction that any file can't be that large, because we use u32 for indexing. And looks like we never try to enforce it anywhere. I think the place to do that would be . Do we have any way to panic without this being marked as ICE? I don't want to thread to each , and this seems like a marginal error where it's totally OK to panic. This is even OK in the IDE context I think: IDE should enforce reasonable max size of the file (something like 10mb, not 4gb) at the virtual file system layer. The "just panic" fix is here:
Do we have any way to panic without this being marked as ICE? or if the context is available.
I tried to compile the same thing in gcc and clang: With gcc: With clang: EDIT: Opened


Question: <ins> error[E0658]: associated const equality is incomplete --> $DIR/dont-ice-on-assoc-projection.rs:15:32 | LL | impl<T> Foo for T where T: Bar<ASSOC = 0> {} |                                ^^^^^^^^^ | = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable error[E0119]: conflicting implementations of trait `Foo` for type `()` --> $DIR/dont-ice-on-assoc-projection.rs:15:1 | LL | impl Foo for () {} | --------------- first implementation here LL | impl<T> Foo for T where T: Bar<ASSOC = 0> {} | ^^^^^^^^^^^^^^^^^ conflicting implementation for `()` error: aborting due to 2 previous errors Some errors have detailed explanations: E0119, E0658. For more information about an error, try `rustc --explain E0119`. </ins>

<!-- 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


Question: <ins> // ignore-tidy-linelength #![deny(intra_doc_resolution_failure)] pub mod char {} /// See also [type@char] // @has intra_link_prim_precedence/struct.MyString.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html' pub struct MyString; /// See also [char] // @has intra_link_prim_precedence/struct.MyString2.html '//a/@href' 'intra_link_prim_precedence/char/index.html' pub struct MyString2; </ins>

I tried to document this code: I expected to see this happen: charstd::char` points to module page of char type points to char primitive page Instead, this happened: type points to module page of char :
I think the problem is that modules are in the type namespace, so is doing exactly what you are asking it for (the module, since it has higher priority). Since the built-in types scope is the lowest precedence, perhaps there needs to be a way to access it directly? Maybe something like or ? Or maybe should skip over modules, and keep looking deeper in the scope hierarchy? (cc )
Oh hmm I see what you mean. There are : Types, values, and macros. Since modules and types are in the same namespace, it uses the first one it finds. Maybe we could work around this by first resolving in an empty module (so it has nothing in scope), then only falling back to the current scope if we don't find something there?
I'm surprised this hasn't caused trouble before now. Does the root of never use the primitive?
I don't know how it works, but the resolver is smart enough to know that in a type context won't match a module (like , the won't match a module named "char". Maybe it has something to do with late-resolution  which has a to give it some context?
Adding that would be more of area ... I can give it a shot though.
It looks like doesn't even return a resolution and only records it for later use ... I'm going to go with the empty module workaround and we can fix it later if it turns out to cause issues.
The double resolve seems hacky. We could probably make type@ specifically not resolve to a module, perhaps? Also, note that modules are in all namespaces
How would that work? We could skip any module resolutions, but since modules have precedence over types I don't know how we'd get the primitive type to resolve afterwards.
Oh hold on we have a function already. We can look at directly.
This doesn't have anything to do with primitives, this has to do with glob imports vs non-glob imports. You can get the same issue with the following:
This also doesn't have to do with modules being "resolved first" or anything. Things that are non-glob in-scope are resolved first.


Question: <ins> // ignore-tidy-linelength #![deny(intra_doc_resolution_failure)] pub mod char {} /// See also [type@char] // @has intra_link_prim_precedence/struct.MyString.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html' pub struct MyString; /// See also [char] // @has intra_link_prim_precedence/struct.MyString2.html '//a/@href' 'intra_link_prim_precedence/char/index.html' pub struct MyString2; </ins>

Actually, my bad: This does have to do with primitives in the sense that primitives are the only thing that still work when shadowed because of some special code in checking the primitive tables. I think when the string matches one of the primitive table entries for TypeNS lookups that were explicitly annotated with type@ and resolve to a module we can hack this in. In the future we might want to tighten up this code so that e.g. can't resolve to an enum, etc.
do you mind if I fix at the same time and resolve primitives even before modules? That seems like the less surprising behavior to me, the module can still be disambiguated with .
I'm a bit wary of doing this because having the char module in scope is not a common situation, and it will get weirder for people who have a different char module. I think we should resolve to whatever is in scope, but if is explicitly mentioned we can then force resolve to the primitive.


Question: (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), // `extern crate foo as bar;` puts `bar` into extern prelude. (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), <ins> // Allows use of the :literal macro fragment specifier (RFC 1576) (accepted, macro_literal_matcher, "1.31.0", Some(35625), None), </ins> ); // If you change this, please modify src/doc/unstable-book as well. You must

Tracking issue for rust-lang/rfcs.
Is anyone working on implementation already? If not I can take a crack at it.
I'll probably do it.
Huh oh, we have an issue already: do we mean to include potentially minus-prefixed literals? If yes, we have a problem because 1. it means we have to return an Expr instead of a Lit, which means I'm not sure one will be able to use the bound fragment in a non-expr context (for example in a static array type?) and 2. it's no longer always a single-TT, so the benefits in terms of future-proofing are a bit less good. If we don't... well, we loose expressivity. I have no idea what is more intuitive though... Would you, as a Rust user, expect to parse ? I certainly can think of use cases for this...
good point. I think I would have expected it, I also agree with the complications.
Can't we upgrade Lit to support negative literals?
I'd expect "literal" (or a future integer-literal specifier) to include (negative 5), but not (the negation of positive 5). Perhaps that expectation doesn't match reality, though. For instance, based on parsing rules for non-literals, I'd expect to act like . So, if handling both and as literals makes this easier, that works. But "literal" definitely needs to include negative numbers, or we'd have a weird user trap to explain.
I'd expect "literal" (or a future integer-literal specifier) to include -5 (negative 5), but not - 5 (the negation of positive 5). Unary operators, including minus, are processed purely by the parser at the moment, no lexer involved. So their treatment is whitespace agnostic. (I personally think this is a good thing.)
I agree with is not syntactically different from and has no reason to be. But I also agree with the fact that the user will probably expect negative numbers to work as literals (even it – syntactically – they're not).
is also supported in literal patterns while arbitrary expressions are not. It'd be reasonable to support it in fragments as well.
Another thing that won't match is a macro call, like , or any of the other macros that I think of as expanding to a literal (, ...).


Question: (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), // `extern crate foo as bar;` puts `bar` into extern prelude. (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), <ins> // Allows use of the :literal macro fragment specifier (RFC 1576) (accepted, macro_literal_matcher, "1.31.0", Some(35625), None), </ins> ); // If you change this, please modify src/doc/unstable-book as well. You must

I dunno, maybe this is not such a good idea after all. Re-reading the RFC in a more skeptical light, I felt like the "Motivation" section could use some more concrete use cases. Maybe this is just failure of imagination on my part, though! I think the likelihood of this feature attracting people who really want constant expressions should be acknowledged as a drawback, too.
That's fine IMO. Personally I'd like it to match only explicit literals in code to distinguish, for example, between literal and identifier and produce different code for them. Right now this is not possible because all of , , are too broad and conflict with each other.
Hi All, I have implemented this feature in my fork of Rust over 1.25.0, under this branch: Following a quick review by a rustc mentor I may have the free time to provide a full pull request for this.
BTW label has the tooltip "implemented in nightly and unstable" but I did not see it there, i.e. commits & pull requests referencing this. Did I miss it?
The implementation that I worked on was merged, yay!
Is there anything stopping an FCP for this?
It's currently merged in unstable; do you mean an FCP to declare it stable?
Yes, an FCP to stabilise. Should have clarified.
Currently, it is not possible to pass a literal from a macro to another macro. . I think this is a bug.
Interesting! That is a bug. I opened to track it.
Agreed, this should be allowed just like passing any other node types.
Is there anything else preventing this from being stabilized? The issue above has been fixed.
This has baked for some time now and I believe it should be ready for stabilization. So let's start the review. merge The feature gate test is here: Unstable book: Tests defined here:
Team member has proposed to merge this. The next step is review by the rest of the tagged teams: [x] [x] [x] [x] [x] [ ] [x] [x] [x] [ ] No concerns currently listed. Once a majority of reviewers approve (and none object), 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!


Question: (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), // `extern crate foo as bar;` puts `bar` into extern prelude. (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), <ins> // Allows use of the :literal macro fragment specifier (RFC 1576) (accepted, macro_literal_matcher, "1.31.0", Some(35625), None), </ins> ); // If you change this, please modify src/doc/unstable-book as well. You must

See for info about what commands tagged team members can give me.
Reading through the tests, I see that is a literal. While that makes sense to me, I remember hearing that it wasn't, but was instead a negation operator and a literal. Am I misremembering?
cc on
I agree that it makes sense. I would say that even if is interpreted as negation + a literal, I would probably still want the macro matcher to accept since that behavior seems more intuitive. In other words, I would see being more as an implementation detail than what a literal is in the mental model.
I think that the nuance with causes a bit of a problem, because I don't think it should be treated as a literal, but I also don't think that the current implementation of would allow detecting it either. You could naïvely allow but that would allow which is clearly wrong.
there are tests currently implemented that verify that is detected as a literal.
I worded that wrong; I meant that only having a matcher and not being able to distinguish strings and numbers means that you can't easily make not a literal.
for procedural macros the input as lexed by the compiler is (two tokens) but procedural macros can create tokens that are negatives (like ). In that sense matching for makes sense to me.
Are literals generated by the compiler counted as true literals? A quick example would be something like: This fails to match, as the expansion, I guess, happens after the selection. I just naively assumed that would have worked.
is not a literal generated by the compiler, it is an identifier followed by an exclamation mark followed by a set of parentheses containing some tokens. See for example: If you were to use it in expression position, it would be interpreted as an invocation of which expands to a string literal. In this case and in your macro though, it is never in a syntactic position where it would be treated as an expression.
I can understand semantically why it doesn't make sense, I just thought it would have, but that being said, I already changed it to , so there's no issue. It just made more sense to me as a literal, because according to the compiler, it could generate a literal from it. I guess it was more a question than an actual issue.
This is true, but there's more to it!


Question: (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), // `extern crate foo as bar;` puts `bar` into extern prelude. (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), <ins> // Allows use of the :literal macro fragment specifier (RFC 1576) (accepted, macro_literal_matcher, "1.31.0", Some(35625), None), </ins> ); // If you change this, please modify src/doc/unstable-book as well. You must

A few built-in macros can expand their arguments eagerly through ~m a g i c~, so they accept and likes even if they expect string literals: Fortunately (or not), this currently cannot be done in user-defined macros.
I actually just realised that I can't change it to , as it's used in . So, I've just had to manually unroll the macro. ! It doesn't look pretty. :( Ninja edit: I just tested what actually happens if you try to pass in a non-literal with . It rejects it the exact same way. Does the already make use of this feature? If not, the seems to propagate the required token. Oh, unless the compiler steps in... That's actually probably the case... I've reverted it back to the type.
: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.
Since you implemented this, would you be willing to write up the stabilization PR?
sure
This appears to be missing from the Rust reference


Question: <ins> // normalize-stderr-test "error `.*`" -> "$$ERROR_MESSAGE" // compile-flags: -o/tmp/ -Zunpretty=ast-tree fn main() {} </ins>

If you , you get a normal error like but if you try to at the same time: rust will panic which is a bit weird. Mayne that panic should be demoted to a regular error? <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
To reproduce: `
claim


Question: <ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // aux-build:issue-25467.rs pub type Issue25467BarT = (); pub type Issue25467FooT = (); extern crate issue_25467 as aux; fn main() { let o: aux::Object = None; } </ins>

It looks like if you go and grab this commit of timely-dataflow from github, you get a nicely reproducible ICE. TravisCI gets it too! In case anything changes in the meantime, the commit you want is Related issues: . The times I've seen this before I haven't be able to reproduce it, but since it seems to happen from a clean pull, I thought I would show you. To repro, just follow the commands here. git clone, cargo build, cargo test. Boom!
It seems like I can make the ICE go away by replacing a member variable with one that uses an equivalent trait which doesn't use associated types: Swapping that in removes the ICE, swapping it out brings the ICE back. So, maybe something isn't working great for boxed traits with associated types. The commit that fixes things is
Doing some testing, and the repro in (not mine) is way simpler. It also explodes on 1.1 stable, with a similar complaint. Just boxing a trait with two associated types.
I run into this problem, too (with stable ).


Question: <ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // aux-build:issue-25467.rs pub type Issue25467BarT = (); pub type Issue25467FooT = (); extern crate issue_25467 as aux; fn main() { let o: aux::Object = None; } </ins>

Hi, I ran into an interesting ICE while working on a personal project. This seems like it could be related to issues or , but I'm not sure. I set up a . The README includes a description of the bug and the compiler backtrace.
Getting the same ICE occasionally in (At more specifically, not minimized because I don't think I can produce a smaller example than the package above).
This is a somewhat flaky ICE I used to see a bunch back in April, but it seemed like it sorted itself out with the 1.0. I've found it again! It is on stable 1.1, so I thought I would bump this post 1.0 issue rather than my open pre-1.0 issues. I'm really not sure what causes this, but the common features tend to be doing a bunch of builds with light changes to a local crate (path="...") on which the project depends (in this case, local edits to the timely crate). It feels a lot like it is Cargo getting just a bit confused about what has changed and what hasn't, as will sometimes fix the problem. Previously, toggling LTO would tickle/untickle the bug, as would insisting on some inlining. Just now, fixed it up, after would not... Maybe someone should just put a on the bounds list... =/


Question: document(w, cx, it) } <ins> fn implementor2item<'a>(cache: &'a Cache, imp : &Implementor) -> Option<&'a clean::Item> { if let Some(t_did) = imp.impl_.for_.def_id() { if let Some(impl_item) = cache.impls.get(&t_did).and_then(|i| i.iter() .find(|i| i.impl_item.def_id == imp.def_id)) { let i = &impl_item.impl_item; return Some(i); } } None } </ins> fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, t: &clean::Trait) -> fmt::Result { let mut bounds = String::new();

It should work a bit like IDE's feature that finds everything that implements a given interface.
This should be a fairly small change (the most annoying part has already been done) so i'll open this up as a mentored issue. The bit that writes out the "Implementors" section is in . This is where the known implementors for a given trait are pulled out of the global context and listed out onto the rendered page. The bit that's responsible for creating links is , implemented on a local type. This kind of Item is easily made from the kind of Item that's otherwise worked on in , but there's a catch: The entries in the Implementors list aren't s. They're s, which are only a subset of the things you get on an Item. This is the "most annoying part" i mentioned earlier. Fortunately, i ran into this when creating the "Implementations on Foreign Types" section, so if you scroll up a little in , you can see so i could render the full impl block for them. The task for anyone who wants to take this on is to pull that up a little so that it's used for all the implementors, not just the foreign ones. With a in hand, combine it with the Context to create a and call to generate the link. ( This also helpfully includes the extra HTML bits that will flush the link to the right edge, which is really the final step.) And... that's it! The link should probably go between the and the where clause underneath it, so that it's aligned with the impl line and not the where clause. You may need to also close/open the that's wrapping the whole line to make sure the link itself isn't monospace. If you have any questions, let me know! Either comment here, or hop onto IRC in , or the impl period Gitter under .


Question: //! paths/files is based on Microsoft's logic in their vcvars bat files, but //! comments can also be found below leading through the various code paths. <del> use std::process::Command; use session::Session; </del> #[cfg(windows)] mod registry; #[cfg(windows)] <del> pub fn link_exe_cmd(sess: &Session) -> Command { </del> <ins> mod platform { </ins> use std::env; use std::ffi::OsString; use std::fs; use std::path::{Path, PathBuf}; <del> use self::registry::{LOCAL_MACHINE}; let arch = &sess.target.target.arch; let (binsub, libsub, vclibsub) = match (bin_subdir(arch), lib_subdir(arch), vc_lib_subdir(arch)) { (Some(x), Some(y), Some(z)) => (x, y, z), _ => return Command::new("link.exe"), }; </del> <ins> use std::process::Command; use session::Session; use super::registry::{LOCAL_MACHINE}; </ins> <del> // First we need to figure out whether the environment is already correctly // configured by vcvars. We do this by looking at the environment variable // `VCINSTALLDIR` which is always set by vcvars, and unlikely to be set // otherwise. If it is defined, then we derive the path to `link.exe` from // that and trust that everything else is configured correctly. // // If `VCINSTALLDIR` wasn't defined (or we couldn't find the linker where it // claimed it should be), then we resort to finding everything ourselves. // First we find where the latest version of MSVC is installed and what // version it is. Then based on the version we find the appropriate SDKs. // // For MSVC 14 (VS 2015) we look for the Win10 SDK and failing that we look // for the Win8.1 SDK. We also look for the Universal CRT. // // For MSVC 12 (VS 2013) we look for the Win8.1 SDK. // // For MSVC 11 (VS 2012) we look for the Win8 SDK. // // For all other versions the user has to execute the appropriate vcvars bat // file themselves to configure the environment. // // If despite our best efforts we are still unable to find MSVC then we just // blindly call `link.exe` and hope for the best. return env::var_os("VCINSTALLDIR").and_then(|dir| { debug!("Environment already configured by user. Assuming it works."); let mut p = PathBuf::from(dir); p.push("bin"); p.push(binsub); p.push("link.exe"); if !p.is_file() { return None } Some(Command::new(p)) }).or_else(|| { get_vc_dir().and_then(|(ver, vcdir)| { debug!("Found VC installation directory {:?}", vcdir); let mut linker = vcdir.clone(); linker.push("bin"); linker.push(binsub); linker.push("link.exe"); if !linker.is_file() { return None } let mut cmd = Command::new(linker); add_lib(&mut cmd, &vcdir.join("lib").join(vclibsub)); if ver == "14.0" { if let Some(dir) = get_ucrt_dir() { debug!("Found Universal CRT {:?}", dir); add_lib(&mut cmd, &dir.join("ucrt").join(libsub)); } if let Some(dir) = get_sdk10_dir() { debug!("Found Win10 SDK {:?}", dir); add_lib(&mut cmd, &dir.join("um").join(libsub)); } else if let Some(dir) = get_sdk81_dir() { debug!("Found Win8.1 SDK {:?}", dir); add_lib(&mut cmd, &dir.join("um").join(libsub)); } } else if ver == "12.0" { if let Some(dir) = get_sdk81_dir() { debug!("Found Win8.1 SDK {:?}", dir); add_lib(&mut cmd, &dir.join("um").join(libsub)); } } else { // ver == "11.0" if let Some(dir) = get_sdk8_dir() { debug!("Found Win8 SDK {:?}", dir); add_lib(&mut cmd, &dir.join("um").join(libsub)); } } Some(cmd) </del> <ins> // Cross toolchains depend on dlls from the host toolchain // We can't just add it to the Command's PATH in `link_exe_cmd` because it // is later overridden so we publicly expose it here instead pub fn host_dll_path() -> Option<PathBuf> { get_vc_dir().and_then(|(_, vcdir)| { host_dll_subdir().map(|sub| { vcdir.join("bin").join(sub) }) </ins> }) <del> }).unwrap_or_else(|| { debug!("Failed to locate linker."); Command::new("link.exe") }); </del> <ins> } pub fn link_exe_cmd(sess: &Session) -> Command { let arch = &sess.target.target.arch; let (binsub, libsub, vclibsub) = match (bin_subdir(arch), lib_subdir(arch), vc_lib_subdir(arch)) { (Some(x), Some(y), Some(z)) => (x, y, z), _ => return Command::new("link.exe"), }; // First we need to figure out whether the environment is already correctly // configured by vcvars. We do this by looking at the environment variable // `VCINSTALLDIR` which is always set by vcvars, and unlikely to be set // otherwise. If it is defined, then we derive the path to `link.exe` from // that and trust that everything else is configured correctly. // // If `VCINSTALLDIR` wasn't defined (or we couldn't find the linker where it // claimed it should be), then we resort to finding everything ourselves. // First we find where the latest version of MSVC is installed and what // version it is. Then based on the version we find the appropriate SDKs. // // For MSVC 14 (VS 2015) we look for the Win10 SDK and failing that we look // for the Win8.1 SDK. We also look for the Universal CRT. // // For MSVC 12 (VS 2013) we look for the Win8.1 SDK. // // For MSVC 11 (VS 2012) we look for the Win8 SDK. // // For all other versions the user has to execute the appropriate vcvars bat // file themselves to configure the environment. // // If despite our best efforts we are still unable to find MSVC then we just // blindly call `link.exe` and hope for the best. return env::var_os("VCINSTALLDIR").and_then(|dir| { debug!("Environment already configured by user. Assuming it works."); let mut p = PathBuf::from(dir); p.push("bin"); p.push(binsub); p.push("link.exe"); if !p.is_file() { return None } Some(Command::new(p)) }).or_else(|| { get_vc_dir().and_then(|(ver, vcdir)| { debug!("Found VC installation directory {:?}", vcdir); let linker = vcdir.clone().join("bin").join(binsub).join("link.exe"); if !linker.is_file() { return None } let mut cmd = Command::new(linker); add_lib(&mut cmd, &vcdir.join("lib").join(vclibsub)); if ver == "14.0" { if let Some(dir) = get_ucrt_dir() { debug!("Found Universal CRT {:?}", dir); add_lib(&mut cmd, &dir.join("ucrt").join(libsub)); } if let Some(dir) = get_sdk10_dir() { debug!("Found Win10 SDK {:?}", dir); add_lib(&mut cmd, &dir.join("um").join(libsub)); } else if let Some(dir) = get_sdk81_dir() { debug!("Found Win8.1 SDK {:?}", dir); add_lib(&mut cmd, &dir.join("um").join(libsub)); } } else if ver == "12.0" { if let Some(dir) = get_sdk81_dir() { debug!("Found Win8.1 SDK {:?}", dir); add_lib(&mut cmd, &dir.join("um").join(libsub)); } } else { // ver == "11.0" if let Some(dir) = get_sdk8_dir() { debug!("Found Win8 SDK {:?}", dir); add_lib(&mut cmd, &dir.join("um").join(libsub)); } } Some(cmd) }) }).unwrap_or_else(|| { debug!("Failed to locate linker."); Command::new("link.exe") }); } </ins> // A convenience function to make the above code simpler fn add_lib(cmd: &mut Command, lib: &Path) { let mut arg: OsString = "/LIBPATH:".into();

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: /// /// A common use for `format!` is concatenation and interpolation of strings. /// The same convention is used with [`print!`] and [`write!`] macros, <del> /// depending on the intended destination of the string. </del> <ins> /// depending on the intended destination of the string; all these macros internally use [`format_args!`]. </ins> /// /// To convert a single value to a string, use the [`to_string`] method. This /// will use the [`Display`] formatting trait. /// <ins> /// To concatenate literals into a `&'static str`, use the [`concat!`] macro. /// </ins> /// [`print!`]: ../std/macro.print.html /// [`write!`]: core::write <ins> /// [`format_args!`]: core::format_args </ins> /// [`to_string`]: crate::string::ToString /// [`Display`]: core::fmt::Display <ins> /// [`concat!`]: core::concat </ins> /// /// # Panics ///

I was sent here from the . Please advise if I am posting in the wrong area. format! macro documentation could be improved by changing one of the examples to be more obvious to new users. Change the example to Additionally, assert! could be used to demonstrate final string values: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Something like ? claim
I think the use of "val" certainly makes it more obvious than my suggestion to use "z". Your suggestion would also do it in one line... I guess the question is whether you would prefer to make it more obvious (readable) by splitting it into two lines. This is my first contribution to Rust in any form, so I'm happy to go with your suggestion.
Thanks all!