-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prohibit parenthesized params in more types. #41856
Prohibit parenthesized params in more types. #41856
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @arielb1 (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
@TimNN thanks for response too! So now I can just wait for review, right? I'm just confused about the meaning of "S-waiting-on-author". |
Sorry for being late on review. There's another case here: https://github.com/qnighy/rust/blob/63ecd6aa0f2c8a6807528d8bdf5eb30211b3fcd4/src/librustc_typeck/astconv.rs#L1395 Example test case: use std::fmt::Display;
fn main() {
let s: Box<Display+std<Display>::marker::Sync()> = Box::new(2);
} Basically every time we access |
Thanks for reviewing, and I found another case which leads to ICE. macro_rules! pathexpr {
($p:path) => ($p);
}
fn main() {
println!("{}", pathexpr!(std::str::from_utf8())(b"Hello").unwrap());
}
|
In summary, we'll have to additionally deal with
macro_rules! pathexpr {
(($($x:tt)*), $p:path, ($($y:tt)*)) => ($($x)* $p $($y)*);
}
mod m1 {
pub struct A {}
pub struct B();
pub struct C;
pub trait Marker {}
}
trait Tr {
type A;
type B;
type C;
fn f();
}
struct D;
impl Tr for D {
type A = m1::A;
type B = m1::B;
type C = m1::C;
fn f() {}
}
// ItemUse
// pathexpr!((use), std::boxed()::Box, (;)); // ERROR from ast_validation
// Visibility
mod m2 {
macro_rules! foo {
($p:path) => { pub(in $p) mod mm {} }
}
// foo!(m2()); // ERROR from ast_validation
}
fn main() {
// QPath::Resolved in PatKind::Struct
// let pathexpr!((), m1()::A , ({})) = m1::A {}; // ERROR from astconv
// let pathexpr!((), m1::A() , ({})) = m1::A {}; // ERROR from astconv
// QPath::Resolved in PatKind::TupleStruct
// let pathexpr!((), m1()::B , (())) = m1::B(); // ERROR from astconv
// let pathexpr!((), m1::B() , (())) = m1::B(); // ICE
// QPath::Resolved in PatKind::Path
// let pathexpr!((), m1()::C , ()) = m1::C; // ERROR from astconv
// let pathexpr!((), m1::C() , ()) = m1::C; // ICE
// QPath::Resolved in ExprPath
// pathexpr!((), m1()::C, ()); // ERROR from astconv
// pathexpr!((), m1::C(), ()); // ICE
// QPath::Resolved in ExprStruct
// pathexpr!((), m1()::A, ({})); // ERROR from astconv
// pathexpr!((), m1::A(), ({})); // ERROR from astconv
// QPath::Resolved in TyPath
// let _ : m1()::C = m1::C; // ERROR from astconv
// let _ : m1::C() = m1::C; // ERROR from astconv
// QPath::TypeRelative in PatKind::Struct
// let pathexpr!((), D::A(), ({})) = m1::A {}; // ERROR from astconv
// QPath::TypeRelative in PatKind::TupleStruct
// let pathexpr!((), D::B(), (())) = m1::B (); // resolution error
// QPath::TypeRelative in PatKind::Path
// let pathexpr!((), D::C, ()) = m1::C; // resolution error
// QPath::TypeRelative in ExprPath
// pathexpr!((), D::f(), ()); // ICE
// QPath::TypeRelative in ExprStruct
// pathexpr!((), D::A(), ({})); // ERROR from astconv
// QPath::TypeRelative in TyPath
// let _ : D::C() = m1::C; // ERROR from astconv
// TraitTyParamBound
{ fn f<X: m1()::Marker>() {} }
// { fn f<X: m1::Marker()>() {} } // type error
// TyTraitObject
let x : &m1()::Marker;
// let x : &m1::Marker(); // type error
let x : &(m1::Marker + Sync());
// ItemDefaultImpl: omitted
// ItemImpl
impl m1()::Marker for u32 {}
// impl m1::Marker() for i32 {} // type error
} |
Dealt with all path segments I found so far. |
@bors r+ |
📌 Commit 2a20073 has been approved by |
⌛ Testing commit 2a20073 with merge a89314f... |
💔 Test failed - status-appveyor |
Oh, this is the first failure for my PR to rust-lang... It is a spurious failure, I suppose? |
…s-in-more-types, r=arielb1 Prohibit parenthesized params in more types. Prohibit parenthesized parameters in primitive types, type parameters, `Self`, etc. Fixes rust-lang#32995.
@bors r- this hit an error on travis https://travis-ci.org/rust-lang/rust/jobs/232310581 |
An existing compile-fail test hit a newly introduced error. This time I ran all tests and it should be fixed. |
@bors r=arielb1 |
📌 Commit e8137d7 has been approved by |
…ypes, r=arielb1 Prohibit parenthesized params in more types. Prohibit parenthesized parameters in primitive types, type parameters, `Self`, etc. Fixes #32995.
@Mark-Simulacrum I suppose no. Is that what I can do by myself? |
I've started builds for a crater run |
I've started the crate build. |
Regressions
Root regressions, sorted by rank:
|
Actual root regressions. All look "intentional" though none seem needed for any reason.
|
Looks like these are legit -- I think we need a warning cycle. @qnighy, a rough description of the procedure for warning cycles is described here on forge. |
I can't believe people actually write this. |
OK, I'll try it. I didn't expect this is actually exploited in several libraries. |
This PR now have two changes:
It seems that only the former one hit regressions. Is it sufficient to only prepare a warning cycle for the former one? |
Prepared the tracking issue for the warning cycle: #42238 |
Added the warning cycle. I wonder if this is sufficient? |
@petrochenkov I can only speak for my own crate, but my guess is that I did some copy-pasta when implementing |
Do we do another crater run then? r+ modulo that. |
Well, let's go @bors r+ |
📌 Commit 9999378 has been approved by |
…ypes, r=arielb1 Prohibit parenthesized params in more types. Prohibit parenthesized parameters in primitive types, type parameters, `Self`, etc. Fixes #32995.
Could anyone tag the tracking issue |
Added tags to #42238; the issue you referenced doesn't appear to be the right tracking issue. |
Thank you, that was just my mistake. |
☀️ Test successful - status-appveyor, status-travis |
Thank you all for reviewing! |
syntax: Relax path grammar TLDR: Accept the disambiguator `::` in "type" paths (`Type::<Args>`), accept the disambiguator `::` before parenthesized generic arguments (`Fn::(Args)`). The "turbofish" disambiguator `::<>` in expression paths is a necessary evil required for path parsing to be both simple and to give reasonable results. Since paths in expressions usually refer to values (but not necessarily, e.g. `Struct::<u8> { field: 0 }` is disambiguated, but refers to a type), people often consider `::<>` to be inherent to *values*, and not *expressions* and want to write disambiguated paths for values even in contexts where disambiguation is not strictly necessary, for example when a path is passed to a macro `m!(Vec::<i32>::new)`. The problem is that currently, if the disambiguator is not *required*, then it's *prohibited*. This results in confusion - see #41740, https://internals.rust-lang.org/t/macro-path-uses-novel-syntax/5561. This PR makes the disambiguator *optional* instead of prohibited in contexts where it's not strictly required, so people can pass paths to macros in whatever form they consider natural (e.g. disambiguated form for value paths). This PR also accepts the disambiguator in paths with parenthesized arguments (`Fn::(Args)`) for consistency and to simplify testing of stuff like #41856 (comment). Closes #41740 cc @rust-lang/lang r? @nikomatsakis
Prohibit parenthesized parameters in primitive types, type parameters,
Self
, etc.Fixes #32995.