Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit052de1d

Browse files
And finally add tests
1 parent1529c66 commit052de1d

File tree

4 files changed

+207
-15
lines changed

4 files changed

+207
-15
lines changed

‎compiler/rustc_lint/src/impl_trait_overcaptures.rs‎

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,89 @@ use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
99
use rustc_middle::ty::{
1010
self,Ty,TyCtxt,TypeSuperVisitable,TypeVisitable,TypeVisitableExt,TypeVisitor,
1111
};
12-
userustc_session::lint::FutureIncompatibilityReason;
13-
userustc_span::edition::Edition;
14-
use rustc_span::{BytePos,Span};
12+
userustc_middle::{bug, span_bug};
13+
userustc_session::{declare_lint, declare_lint_pass};
14+
use rustc_span::{sym,BytePos,Span};
1515

1616
usecrate::fluent_generatedas fluent;
1717
usecrate::{LateContext,LateLintPass};
1818

19-
// TODO: feature gate these too
20-
2119
declare_lint!{
22-
/// UwU
20+
/// The `impl_trait_overcaptures` lint warns against cases where lifetime
21+
/// capture behavior will differ in edition 2024.
22+
///
23+
/// In the 2024 edition, `impl Trait`s will capture all lifetimes in scope,
24+
/// rather than just the lifetimes that are mentioned in the bounds of the type.
25+
/// Often these sets are equal, but if not, it means that the `impl Trait` may
26+
/// cause erroneous borrow-checker errors.
27+
///
28+
/// ### Example
29+
///
30+
/// ```rust,compile_fail
31+
/// # #![feature(precise_capturing)]
32+
/// # #![allow(incomplete_features)]
33+
/// # #![deny(impl_trait_overcaptures)]
34+
/// # use std::fmt::Display;
35+
/// let mut x = vec![];
36+
/// x.push(1);
37+
///
38+
/// fn test(x: &Vec<i32>) -> impl Display {
39+
/// x[0]
40+
/// }
41+
///
42+
/// let element = test(&x);
43+
/// x.push(2);
44+
/// println!("{element}");
45+
/// ```
46+
///
47+
/// {{produces}}
48+
///
49+
/// ### Explanation
50+
///
51+
/// In edition < 2024, the returned `impl Display` doesn't capture the
52+
/// lifetime from the `&Vec<i32>`, so the vector can be mutably borrowed
53+
/// while the `impl Display` is live.
54+
///
55+
/// To fix this, we can explicitly state that the `impl Display` doesn't
56+
/// capture any lifetimes, using `impl use<> Display`.
2357
pubIMPL_TRAIT_OVERCAPTURES,
2458
Allow,
25-
"will capture more lifetimes than possibly intended in edition 2024",
26-
@future_incompatible =FutureIncompatibleInfo{
27-
reason:FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
28-
reference:"<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>",
29-
};
59+
"`impl Trait` will capture more lifetimes than possibly intended in edition 2024",
60+
@feature_gate = sym::precise_capturing;
61+
//@future_incompatible = FutureIncompatibleInfo {
62+
// reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
63+
// reference: "<FIXME>",
64+
//};
3065
}
3166

3267
declare_lint!{
33-
/// UwU
68+
/// The `impl_trait_redundant_captures` lint warns against cases where use of the
69+
/// precise capturing `use<...>` syntax is not needed.
70+
///
71+
/// In the 2024 edition, `impl Trait`s will capture all lifetimes in scope.
72+
/// If precise-capturing `use<...>` syntax is used, and the set of parameters
73+
/// that are captures are *equal* to the set of parameters in scope, then
74+
/// the syntax is redundant, and can be removed.
75+
///
76+
/// ### Example
77+
///
78+
/// ```rust,compile_fail
79+
/// # #![feature(precise_capturing, lifetime_capture_rules_2024)]
80+
/// # #![allow(incomplete_features)]
81+
/// # #![deny(impl_trait_redundant_captures)]
82+
/// fn test<'a>(x: &'a i32) -> impl use<'a> Sized { x }
83+
/// ```
84+
///
85+
/// {{produces}}
86+
///
87+
/// ### Explanation
88+
///
89+
/// To fix this, remove the `use<'a>`, since the lifetime is already captured
90+
/// since it is in scope.
3491
pubIMPL_TRAIT_REDUNDANT_CAPTURES,
3592
Warn,
36-
"uwu 2"
93+
"redundant precise-capturing `use<...>` syntax on an `impl Trait`",
94+
@feature_gate = sym::precise_capturing;
3795
}
3896

3997
declare_lint_pass!(
@@ -106,7 +164,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
106164
for argin t.bound_vars(){
107165
let arg: ty::BoundVariableKind = arg;
108166
match arg{
109-
ty::BoundVariableKind::Region(ty::BoundRegionKind::BrNamed(def_id, ..)) =>{
167+
ty::BoundVariableKind::Region(ty::BoundRegionKind::BrNamed(def_id, ..))
168+
| ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id, _)) =>{
110169
added.push(def_id);
111170
let unique =self.in_scope_parameters.insert(def_id);
112171
assert!(unique);
@@ -265,7 +324,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
265324
}
266325
_ =>{
267326
self.tcx.dcx().span_delayed_bug(
268-
self.tcx().hir().span(arg.hir_id()),
327+
self.tcx.hir().span(arg.hir_id()),
269328
"no valid for captured arg",
270329
);
271330
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//@ run-rustfix
2+
3+
#![feature(precise_capturing)]
4+
#![allow(unused, incomplete_features)]
5+
#![deny(impl_trait_overcaptures)]
6+
7+
fn named<'a>(x: &'a i32) -> impl use<> Sized { *x }
8+
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
9+
10+
fn implicit(x: &i32) -> impl use<> Sized { *x }
11+
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
12+
13+
struct W;
14+
impl W {
15+
fn hello(&self, x: &i32) -> impl use<'_> Sized + '_ { self }
16+
//~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024
17+
}
18+
19+
trait Higher<'a> {
20+
type Output;
21+
}
22+
impl Higher<'_> for () {
23+
type Output = ();
24+
}
25+
26+
fn hrtb() -> impl for<'a> Higher<'a, Output = impl use<> Sized> {}
27+
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
28+
29+
fn main() {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//@ run-rustfix
2+
3+
#![feature(precise_capturing)]
4+
#![allow(unused, incomplete_features)]
5+
#![deny(impl_trait_overcaptures)]
6+
7+
fnnamed<'a>(x:&'ai32) ->implSized{*x}
8+
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
9+
10+
fnimplicit(x:&i32) ->implSized{*x}
11+
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
12+
13+
structW;
14+
implW{
15+
fnhello(&self,x:&i32) ->implSized +'_{self}
16+
//~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024
17+
}
18+
19+
traitHigher<'a>{
20+
typeOutput;
21+
}
22+
implHigher<'_>for(){
23+
typeOutput =();
24+
}
25+
26+
fnhrtb() ->implfor<'a>Higher<'a,Output =implSized>{}
27+
//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
28+
29+
fnmain(){}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
2+
--> $DIR/overcaptures-2024.rs:7:29
3+
|
4+
LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
5+
| ^^^^^^^^^^
6+
|
7+
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
8+
--> $DIR/overcaptures-2024.rs:7:10
9+
|
10+
LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
11+
| ^^
12+
= note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
13+
note: the lint level is defined here
14+
--> $DIR/overcaptures-2024.rs:5:9
15+
|
16+
LL | #![deny(impl_trait_overcaptures)]
17+
| ^^^^^^^^^^^^^^^^^^^^^^^
18+
help: use the precise capturing `use<...>` syntax to make the captures explicit
19+
|
20+
LL | fn named<'a>(x: &'a i32) -> impl use<> Sized { *x }
21+
| +++++
22+
23+
error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
24+
--> $DIR/overcaptures-2024.rs:10:25
25+
|
26+
LL | fn implicit(x: &i32) -> impl Sized { *x }
27+
| ^^^^^^^^^^
28+
|
29+
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
30+
--> $DIR/overcaptures-2024.rs:10:16
31+
|
32+
LL | fn implicit(x: &i32) -> impl Sized { *x }
33+
| ^
34+
= note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
35+
help: use the precise capturing `use<...>` syntax to make the captures explicit
36+
|
37+
LL | fn implicit(x: &i32) -> impl use<> Sized { *x }
38+
| +++++
39+
40+
error: `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024
41+
--> $DIR/overcaptures-2024.rs:15:33
42+
|
43+
LL | fn hello(&self, x: &i32) -> impl Sized + '_ { self }
44+
| ^^^^^^^^^^^^^^^
45+
|
46+
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
47+
--> $DIR/overcaptures-2024.rs:15:24
48+
|
49+
LL | fn hello(&self, x: &i32) -> impl Sized + '_ { self }
50+
| ^
51+
= note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
52+
help: use the precise capturing `use<...>` syntax to make the captures explicit
53+
|
54+
LL | fn hello(&self, x: &i32) -> impl use<'_> Sized + '_ { self }
55+
| +++++++
56+
57+
error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
58+
--> $DIR/overcaptures-2024.rs:26:47
59+
|
60+
LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
61+
| ^^^^^^^^^^
62+
|
63+
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
64+
--> $DIR/overcaptures-2024.rs:26:23
65+
|
66+
LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
67+
| ^^
68+
= note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
69+
help: use the precise capturing `use<...>` syntax to make the captures explicit
70+
|
71+
LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl use<> Sized> {}
72+
| +++++
73+
74+
error: aborting due to 4 previous errors
75+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp