-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Tracking issue for future-incompatibility lint patterns_in_fns_without_body
#35203
Comments
Properly enforce the "patterns aren't allowed in foreign functions" rule Cases like `arg @ PATTERN` or `mut arg` were missing. Apply the same rule to function pointer types. Closes #35203 [breaking-change], no breakage in sane code is expected though r? @nikomatsakis This is somewhat related to rust-lang/rfcs#1685 (cc @matklad). The goal is to eventually support full pattern syntax where it makes sense (function body may present) and to support *only* the following forms - `TYPE`, `ident: TYPE`, `_: TYPE` - where patterns don't make sense (function body doesn't present), i.e. in foreign functions and function pointer types.
Prohibit patterns in trait methods without bodies They are not properly type checked ```rust trait Tr { fn f(&a: u8); // <- This compiles } ``` , mostly rejected by the parser already and generally don't make much sense. This PR is kind of a missing part of rust-lang#35015. Needs crater run. cc rust-lang#35078 (comment) rust-lang#35015 rust-lang/rfcs#1685 rust-lang#35203 r? @eddyb
Prohibit patterns in trait methods without bodies They are not properly type checked ```rust trait Tr { fn f(&a: u8); // <- This compiles } ``` , mostly rejected by the parser already and generally don't make much sense. This PR is kind of a missing part of #35015. Given the [statistics from crater](#37378 (comment)), the effect of this PR is mostly equivalent to improving `unused_mut` lint. cc #35078 (comment) #35015 rust-lang/rfcs#1685 #35203 r? @eddyb
@sanxiyn |
These are deprecated and will become a hard error in the future, see rust-lang/rust#35203
https://github.com/xfix/extension-trait uses patterns in functions without body to use the same signature for a trait and its implementation. Due to |
Accept interpolated patterns in trait method parameters Permit this, basically ```rust macro_rules! m { ($pat: pat) => { trait Tr { fn f($pat: u8) {} } } } ``` it previously caused a parsing error during expansion because trait methods accept only very restricted set of patterns during parsing due to ambiguities caused by [anonymous parameters](#41686), and this set didn't include interpolated patterns. Some outdated messages from "no patterns allowed" errors are also removed. Addresses #35203 (comment)
@petrochenkov Awesome! |
Transition some C-future-compatibility lints to {ERROR, DENY} Closes #40107 (ERROR). Closes #39207 (ERROR). Closes #37872 (ERROR). Closes #36887 (ERROR). Closes #36247 (ERROR. Closes #42238 (ERROR). Transitions #59014 (DENY). Transitions #57571 (DENY). Closes #60210 (ERROR). Transitions #35203 (DENY). r? @petrochenkov
Hi there, today I found that define something like fn into_blah(mut self) in a trait trigger this error. I wonder if this is intended behavior. |
@yangzhe1990 Yep; that's intended behavior, at least for now. |
Transition future compat lints to {ERROR, DENY} - Take 2 Follow up to rust-lang#63247 implementing rust-lang#63247 (comment). - `legacy_ctor_visibility` (ERROR) -- closes rust-lang#39207 - `legacy_directory_ownership` (ERROR) -- closes rust-lang#37872 - `safe_extern_static` (ERROR) -- closes rust-lang#36247 - `parenthesized_params_in_types_and_modules` (ERROR) -- closes rust-lang#42238 - `duplicate_macro_exports` (ERROR) - `nested_impl_trait` (ERROR) -- closes rust-lang#59014 - `ill_formed_attribute_input` (DENY) -- transitions rust-lang#57571 - `patterns_in_fns_without_body` (DENY) -- transitions rust-lang#35203 r? @varkor cc @petrochenkov
Transition future compat lints to {ERROR, DENY} - Take 2 Follow up to rust-lang#63247 implementing rust-lang#63247 (comment). - `legacy_ctor_visibility` (ERROR) -- closes rust-lang#39207 - `legacy_directory_ownership` (ERROR) -- closes rust-lang#37872 - `safe_extern_static` (ERROR) -- closes rust-lang#36247 - `parenthesized_params_in_types_and_modules` (ERROR) -- closes rust-lang#42238 - `duplicate_macro_exports` (ERROR) - `nested_impl_trait` (ERROR) -- closes rust-lang#59014 - `ill_formed_attribute_input` (DENY) -- transitions rust-lang#57571 - `patterns_in_fns_without_body` (DENY) -- transitions rust-lang#35203 r? @varkor cc @petrochenkov
Looks rust is giving me this error without suggestion, I didn't know the fix was just simply removing codeuse std::mem;
pub trait NewDedup<T> {
fn partition_dedup_new(&mut self) -> (&mut [T], &mut [T])
where
T: PartialEq<T>,
{
self.partition_dedup_by_new(|a, b| a == b)
}
fn partition_dedup_by_new<F>(&mut self, mut same_bucket: F) -> (&mut [T], &mut [T])
where
F: FnMut(&mut T, &mut T) -> bool;
}
impl<T> NewDedup<T> for &mut [T] {
fn partition_dedup_by_new<F>(&mut self, mut same_bucket: F) -> (&mut [T], &mut [T])
where
F: FnMut(&mut T, &mut T) -> bool,
{
let len = self.len();
if len <= 1 {
return (self, &mut []);
}
let ptr = self.as_mut_ptr();
let mut next_read: usize = 1;
let mut next_write: usize = 1;
// SAFETY: the `while` condition guarantees `next_read` and `next_write`
// are less than `len`, thus are inside `self`. `prev_ptr_write` points to
// one element before `ptr_write`, but `next_write` starts at 1, so
// `prev_ptr_write` is never less than 0 and is inside the slice.
// This fulfils the requirements for dereferencing `ptr_read`, `prev_ptr_write`
// and `ptr_write`, and for using `ptr.add(next_read)`, `ptr.add(next_write - 1)`
// and `prev_ptr_write.offset(1)`.
//
// `next_write` is also incremented at most once per loop at most meaning
// no element is skipped when it may need to be swapped.
//
// `ptr_read` and `prev_ptr_write` never point to the same element. This
// is required for `&mut *ptr_read`, `&mut *prev_ptr_write` to be safe.
// The explanation is simply that `next_read >= next_write` is always true,
// thus `next_read > next_write - 1` is too.
unsafe {
// Avoid bounds checks by using raw pointers.
while next_read < len {
let ptr_read = ptr.add(next_read);
let prev_ptr_write = ptr.add(next_write - 1);
if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) {
next_write += 1;
next_read += 1;
// Avoid checking next_write != next_read once it is not in the same bucket,
// always swap memory if it is not in the same bucket.
while next_read < len {
let ptr_read = ptr.add(next_read);
let prev_ptr_write = ptr.add(next_write - 1);
if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) {
let ptr_write = prev_ptr_write.offset(1);
mem::swap(&mut *ptr_read, &mut *ptr_write);
next_write += 1;
}
next_read += 1;
}
return self.split_at_mut(next_write);
}
next_read += 1;
}
}
self.split_at_mut(next_write)
}
} |
Possible reason for this to stay around: macros. While I never write code like this by hand, I just happened to generate code that hit this warning by auto-generating a trait definition based on a provided implementation. Without any way to cleanly extract a function header, it's stupidly difficult to avoid this warning in a situation like this. |
Another use case: hinting to auto-completion tools like rust-analyzer, which will copy parameter names, patterns, etc. when auto-implementing a trait. Just tried to make a parameter default to |
patterns_in_fns_without_body
Code using patterns in parameters of foreign functions, function pointers or trait methods without body is not accepted by the compiler.
Previously some simple patterns like
&ident
,&&ident
ormut ident
were allowed in these positions, now they aren't. Such patterns weren't properly type checked, e.g.type A = fn(&arg: u8);
compiled despiteu8
not being a reference.What are these errors for?
Full patterns don't make sense in functions without bodies, but simple identifiers may be useful for documenting argument purposes even if they aren't actually used -
type Callback = fn(useful_name: u8)
.By restricting patterns in body-less function signatures to
ident: TYPE
we can make argument names optional and accept simply aTYPE
in argument position (type T = fn(u8)
) without introducing parsing ambiguities.How to fix this warning/error
Remove
&
ormut
from the pattern and make the function parameter a single identifier or_
.Current status
mut IDENT
The text was updated successfully, but these errors were encountered: