Code change:
<ins> // error-pattern: `#[panic_handler]` function required, but not found // Regression test for #54505 - range borrowing suggestion had // incorrect syntax (missing parentheses). // This test doesn't use std // (so all Ranges resolve to core::ops::Range...) #![no_std] #![feature(lang_items)] use core::ops::RangeBounds; #[cfg(not(target_arch = "wasm32"))] #[lang = "eh_personality"] extern fn eh_personality() {} #[cfg(target_os = "windows")] #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..1) take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(1..) take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..) take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..=1) take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..5) take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..=42) } </ins>

Related discussion:
text: Here's how I rationalize it: because they are parsed and desugared by the compiler, the check needs to be explicit and hardcode all paths to builtin ranges. Handle a special case with a special case.
Yes, this is where the lowering code comes in handy, because you can see exactly how the different syntax is desugared differently, to make sure you really are catching all the cases. Yes, I agree. It'd be nice if there was a more uniform way to handle them, but it's not convenient at the moment. You could include a reference back to in a comment to where the desugaring takes place, which will provide some motivation for matching in .
All clear now, thanks. I have succeeded in matching all range types and getting the test to pass. Needs some cleanups, but hopefully should be ready for PR soon. I have a few more questions before that though :smile: I have noticed that most of my code would actually be irrelevant if I re-used functions and constants defined in , e.g.: Can't deny that I have used these as inspiration / guideline (albeit I did not do a stupid copy-paste). What's the policy on using clippy code (clippy is a submodule of main repo)? This is purely in the interest of pursuing . The diff is not that big (52 new lines to , fairly specific to matching paths) -- but still, my clean code sense tingles because of possible DRY violation. Another conundrum I have is whether we should address and paths (and if so, how to work out we're not using at compile time)?
Unfortunately, there's not much sharing from clippy to rustc. I wouldn't worry about it. If you can encapsulate it easily, it's possible that clippy could make use of the code in rustc instead. The function in picks the correct path for / — you should be able to use that.
Thanks for the suggestion for , unfortunately I can't really make the association of and . It seems to me they are disjoint -- in : lowering happens in , whereas typechecking happens in . in takes : The it uses needs an awful lot of things to be instantiated. Not sure if I can get the hold of it all in .