Code change:
<ins> // run-rustfix // Regression test for changes introduced while fixing #54505 // This test uses non-literals for Ranges // (expecting no parens with borrow suggestion) use std::ops::RangeBounds; // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(&std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } take_range(&::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } take_range(&std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFrom { start: 1 } take_range(&::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } take_range(&std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFull {} take_range(&::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFull {} take_range(&std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) take_range(&::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) take_range(&std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeTo { end: 5 } take_range(&::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeTo { end: 5 } take_range(&std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } take_range(&::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } } </ins>

Related discussion:
text: (I'm not aware of a facility to do this easily already.) I think manually going through the possible s and checking that the parenthesisation behaviour is correct in each case would be a lot simpler: if we handle the different s in an exhaustive now (it's likely that if the ranges were handled incorrectly, there could be some others that are also missed at the moment), then this should be a one-time fix and the tests should prevent it regressing. A simple UI test should be sufficient here: will generate the output files, which will include all the relevant notes.
There was a similar problem with the suggestions, and it was fixed in . Further use of the operator precedence list can be seen in (which introduced the error fixed in the other PR).
Thanks for your guidance and much appreciated. I have dug into HIR and built-in ranges a bit more. Decided to check all the built-in range types and concluded they are all indeed affected by this problem. The following test I came up with demonstrates my intended fix (fails with nightly as well as stage 1 compiled from master): None of the fix suggestions, when applied, constitute valid syntax. My test checks for syntax I believe should be suggested by the compiler. I'm keen to tackle all of the range types at once in the scope of this issue. The problem I see though is just how wildly different each of the range types is represented in HIR. Adding a call just above this line: Revealed the following: for isfor isfor isfor isfor isfor is I'm quite bewildered by this non-uniformity and I guess I need some help unifying all of these into a elegant condition to tell "is this a built-in range?". I could probably brute-force it in a with explicit checks for , but maybe we can do better. Thanks in advance! EDIT realized that this non-uniformity was actually mentioned in the second comment from , but my plea still stands. Thanks for your patience.
I think you can match on all of these with something along the lines of (pseudocode):
Right, that's what I had in mind, but was also wondering if something like a check for  trait would work better. I guess we want to match against built-in range literals though, and explicitly.