Skip to content

Commit 9c6320a

Browse files
committed
Apply mismatched-lifetime-syntaxes to trait and extern functions
1 parent d00435f commit 9c6320a

File tree

5 files changed

+140
-10
lines changed

5 files changed

+140
-10
lines changed

compiler/rustc_lint/src/lifetime_syntax.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,45 @@ impl<'tcx> LateLintPass<'tcx> for LifetimeSyntax {
8484
_: rustc_span::Span,
8585
_: rustc_span::def_id::LocalDefId,
8686
) {
87-
let mut input_map = Default::default();
88-
let mut output_map = Default::default();
87+
check_fn_like(cx, fd);
88+
}
8989

90-
for input in fd.inputs {
91-
LifetimeInfoCollector::collect(input, &mut input_map);
90+
#[instrument(skip_all)]
91+
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, ti: &'tcx hir::TraitItem<'tcx>) {
92+
match ti.kind {
93+
hir::TraitItemKind::Const(..) => {}
94+
hir::TraitItemKind::Fn(fn_sig, _trait_fn) => check_fn_like(cx, fn_sig.decl),
95+
hir::TraitItemKind::Type(..) => {}
9296
}
97+
}
9398

94-
if let hir::FnRetTy::Return(output) = fd.output {
95-
LifetimeInfoCollector::collect(output, &mut output_map);
99+
#[instrument(skip_all)]
100+
fn check_foreign_item(
101+
&mut self,
102+
cx: &LateContext<'tcx>,
103+
fi: &'tcx rustc_hir::ForeignItem<'tcx>,
104+
) {
105+
match fi.kind {
106+
hir::ForeignItemKind::Fn(fn_sig, _idents, _generics) => check_fn_like(cx, fn_sig.decl),
107+
hir::ForeignItemKind::Static(..) => {}
108+
hir::ForeignItemKind::Type => {}
96109
}
110+
}
111+
}
112+
113+
fn check_fn_like<'tcx>(cx: &LateContext<'tcx>, fd: &'tcx hir::FnDecl<'tcx>) {
114+
let mut input_map = Default::default();
115+
let mut output_map = Default::default();
97116

98-
report_mismatches(cx, &input_map, &output_map);
117+
for input in fd.inputs {
118+
LifetimeInfoCollector::collect(input, &mut input_map);
99119
}
120+
121+
if let hir::FnRetTy::Return(output) = fd.output {
122+
LifetimeInfoCollector::collect(output, &mut output_map);
123+
}
124+
125+
report_mismatches(cx, &input_map, &output_map);
100126
}
101127

102128
#[instrument(skip_all)]

tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ where
2020
Self: Sized,
2121
{
2222
type I: for<'a> FamilyLt<'a>;
23-
fn inject(_: &()) -> <Self::I as FamilyLt>::Out;
23+
fn inject(_: &()) -> <Self::I as FamilyLt<'_>>::Out;
2424
}
2525

2626
impl<T: 'static> Inject for RefMutFamily<T> {

tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,45 @@ mod diagnostic_output {
220220
}
221221
}
222222

223+
/// Trait functions are represented differently in the HIR. Make sure
224+
/// we visit them.
225+
mod trait_functions {
226+
#[derive(Copy, Clone)]
227+
struct ContainsLifetime<'a>(&'a u8);
228+
229+
trait TheTrait {
230+
fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime;
231+
//~^ ERROR lifetime flowing from input to output with different syntax
232+
233+
fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime;
234+
//~^ ERROR lifetime flowing from input to output with different syntax
235+
}
236+
237+
impl TheTrait for &u8 {
238+
fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime {
239+
//~^ ERROR lifetime flowing from input to output with different syntax
240+
ContainsLifetime(v)
241+
}
242+
243+
fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime {
244+
//~^ ERROR lifetime flowing from input to output with different syntax
245+
ContainsLifetime(self)
246+
}
247+
}
248+
}
249+
250+
/// Extern functions are represented differently in the HIR. Make sure
251+
/// we visit them.
252+
mod foreign_functions {
253+
#[derive(Copy, Clone)]
254+
struct ContainsLifetime<'a>(&'a u8);
255+
256+
extern "Rust" {
257+
fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime;
258+
//~^ ERROR lifetime flowing from input to output with different syntax
259+
}
260+
}
261+
223262
/// These usages are expected to **not** trigger the lint
224263
mod acceptable_uses {
225264
#[derive(Copy, Clone)]

tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,5 +469,70 @@ help: one option is to consistently use `'a`
469469
LL | fn multiple_outputs<'a>(v: &'a u8) -> (&'a u8, &'a u8) {
470470
| ++ ++
471471

472-
error: aborting due to 34 previous errors
472+
error: lifetime flowing from input to output with different syntax can be confusing
473+
--> $DIR/mismatched-lifetime-syntaxes.rs:230:45
474+
|
475+
LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime;
476+
| ^^^ ---------------- the lifetime gets resolved as `'_`
477+
| |
478+
| this lifetime flows to the output
479+
|
480+
help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
481+
|
482+
LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_>;
483+
| ++++
484+
485+
error: lifetime flowing from input to output with different syntax can be confusing
486+
--> $DIR/mismatched-lifetime-syntaxes.rs:233:49
487+
|
488+
LL | fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime;
489+
| ^^^^^ ---------------- the lifetime gets resolved as `'_`
490+
| |
491+
| this lifetime flows to the output
492+
|
493+
help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
494+
|
495+
LL | fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime<'_>;
496+
| ++++
497+
498+
error: lifetime flowing from input to output with different syntax can be confusing
499+
--> $DIR/mismatched-lifetime-syntaxes.rs:238:45
500+
|
501+
LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime {
502+
| ^^^ ---------------- the lifetime gets resolved as `'_`
503+
| |
504+
| this lifetime flows to the output
505+
|
506+
help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
507+
|
508+
LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> {
509+
| ++++
510+
511+
error: lifetime flowing from input to output with different syntax can be confusing
512+
--> $DIR/mismatched-lifetime-syntaxes.rs:243:49
513+
|
514+
LL | fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime {
515+
| ^^^^^ ---------------- the lifetime gets resolved as `'_`
516+
| |
517+
| this lifetime flows to the output
518+
|
519+
help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
520+
|
521+
LL | fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime<'_> {
522+
| ++++
523+
524+
error: lifetime flowing from input to output with different syntax can be confusing
525+
--> $DIR/mismatched-lifetime-syntaxes.rs:257:45
526+
|
527+
LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime;
528+
| ^^^ ---------------- the lifetime gets resolved as `'_`
529+
| |
530+
| this lifetime flows to the output
531+
|
532+
help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
533+
|
534+
LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_>;
535+
| ++++
536+
537+
error: aborting due to 39 previous errors
473538

tests/ui/traits/associated_type_bound/hrtb-associated.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub trait Provides<'a> {
1010
pub trait Selector: for<'a> Provides<'a> {
1111
type Namespace: PartialEq + for<'a> PartialEq<<Self as Provides<'a>>::Item>;
1212

13-
fn get_namespace(&self) -> <Self as Provides>::Item;
13+
fn get_namespace(&self) -> <Self as Provides<'_>>::Item;
1414
}
1515

1616
pub struct MySelector;

0 commit comments

Comments
 (0)