Skip to content

Commit f5e9cb5

Browse files
authored
Rollup merge of #97720 - cjgillot:all-fresh, r=petrochenkov
Always create elided lifetime parameters for functions Anonymous and elided lifetimes in functions are sometimes (async fns) --and sometimes not (regular fns)-- desugared to implicit generic parameters. This difference of treatment makes it some downstream analyses more complicated to handle. This step is a pre-requisite to perform lifetime elision resolution on AST. There is currently an inconsistency in the treatment of argument-position impl-trait for functions and async fns: ```rust trait Foo<'a> {} fn foo(t: impl Foo<'_>) {} //~ ERROR missing lifetime specifier async fn async_foo(t: impl Foo<'_>) {} //~ OK fn bar(t: impl Iterator<Item = &'_ u8>) {} //~ ERROR missing lifetime specifier async fn async_bar(t: impl Iterator<Item = &'_ u8>) {} //~ OK ``` The current implementation reports "missing lifetime specifier" on `foo`, but **accepts it** in `async_foo`. This PR **proposes to accept** the anonymous lifetime in both cases as an extra generic lifetime parameter. This change would be insta-stable, so let's ping t-lang. Anonymous lifetimes in GAT bindings keep being forbidden: ```rust fn foo(t: impl Foo<Assoc<'_> = Bar<'_>>) {} ^^ ^^ forbidden ok ``` I started a discussion here: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Anonymous.20lifetimes.20in.20universal.20impl-trait/near/284968606 r? ``@petrochenkov``
2 parents 431c6f8 + 5a20834 commit f5e9cb5

20 files changed

+163
-56
lines changed

compiler/rustc_feature/src/active.rs

+2
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ declare_features! (
148148
/// below (it has to be checked before expansion possibly makes
149149
/// macros disappear).
150150
(active, allow_internal_unstable, "1.0.0", None, None),
151+
/// Allows using anonymous lifetimes in argument-position impl-trait.
152+
(active, anonymous_lifetime_in_impl_trait, "1.63.0", None, None),
151153
/// Allows identifying the `compiler_builtins` crate.
152154
(active, compiler_builtins, "1.13.0", None, None),
153155
/// Outputs useful `assert!` messages

compiler/rustc_resolve/src/late.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,10 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
758758
// We don't need to deal with patterns in parameters, because
759759
// they are not possible for foreign or bodiless functions.
760760
self.with_lifetime_rib(
761-
LifetimeRibKind::AnonymousPassThrough(fn_id, false),
761+
LifetimeRibKind::AnonymousCreateParameter {
762+
binder: fn_id,
763+
report_in_path: false,
764+
},
762765
|this| walk_list!(this, visit_param, &sig.decl.inputs),
763766
);
764767
self.with_lifetime_rib(
@@ -792,18 +795,13 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
792795
// generic parameters. This is especially useful for `async fn`, where
793796
// these fresh generic parameters can be applied to the opaque `impl Trait`
794797
// return type.
795-
let rib = if async_node_id.is_some() {
796-
// Only emit a hard error for `async fn`, since this kind of
797-
// elision has always been allowed in regular `fn`s.
798+
this.with_lifetime_rib(
798799
LifetimeRibKind::AnonymousCreateParameter {
799800
binder: fn_id,
800-
report_in_path: true,
801-
}
802-
} else {
803-
LifetimeRibKind::AnonymousPassThrough(fn_id, false)
804-
};
805-
this.with_lifetime_rib(
806-
rib,
801+
// Only emit a hard error for `async fn`, since this kind of
802+
// elision has always been allowed in regular `fn`s.
803+
report_in_path: async_node_id.is_some(),
804+
},
807805
// Add each argument to the rib.
808806
|this| this.resolve_params(&declaration.inputs),
809807
);

compiler/rustc_resolve/src/late/lifetimes.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -1677,14 +1677,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
16771677
break None;
16781678
}
16791679

1680-
Scope::Binder { ref lifetimes, scope_type, s, .. } => {
1680+
Scope::Binder { ref lifetimes, scope_type, s, where_bound_origin, .. } => {
16811681
if let Some(&def) = lifetimes.get(&region_def_id) {
16821682
break Some(def.shifted(late_depth));
16831683
}
16841684
match scope_type {
16851685
BinderScopeType::Normal => late_depth += 1,
16861686
BinderScopeType::Concatenating => {}
16871687
}
1688+
// Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
1689+
// regular fns.
1690+
if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
1691+
&& let hir::LifetimeName::Param(_, hir::ParamName::Fresh) = lifetime_ref.name
1692+
&& let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner)
1693+
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
1694+
{
1695+
rustc_session::parse::feature_err(
1696+
&self.tcx.sess.parse_sess,
1697+
sym::anonymous_lifetime_in_impl_trait,
1698+
lifetime_ref.span,
1699+
"anonymous lifetimes in `impl Trait` are unstable",
1700+
).emit();
1701+
return;
1702+
}
16881703
scope = s;
16891704
}
16901705

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ symbols! {
341341
always,
342342
and,
343343
and_then,
344+
anonymous_lifetime_in_impl_trait,
344345
any,
345346
append_const_msg,
346347
arbitrary_enum_discriminant,

src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl CustomStruct {
9393

9494
fn test_alias(
9595
value: CustomAlias,
96-
reference: &CustomAlias, //~ ERROR passing `CustomAlias<>` by reference
96+
reference: &CustomAlias, //~ ERROR passing `CustomAlias<'_>` by reference
9797
) {
9898
}
9999
}

src/test/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ error: passing `CustomStruct` by reference
9494
LL | reference: &CustomStruct,
9595
| ^^^^^^^^^^^^^ help: try passing by value: `CustomStruct`
9696

97-
error: passing `CustomAlias<>` by reference
97+
error: passing `CustomAlias<'_>` by reference
9898
--> $DIR/rustc_pass_by_value.rs:96:20
9999
|
100100
LL | reference: &CustomAlias,
101-
| ^^^^^^^^^^^^ help: try passing by value: `CustomAlias<>`
101+
| ^^^^^^^^^^^^ help: try passing by value: `CustomAlias<'_>`
102102

103103
error: passing `WithParameters<T, 1>` by reference
104104
--> $DIR/rustc_pass_by_value.rs:110:20

src/test/ui/generic-associated-types/bugs/issue-87748.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ error[E0478]: lifetime bound not satisfied
44
LL | fn do_sth(_: u32) {}
55
| ^^^^^^^^^^^^^^^^^
66
|
7-
note: lifetime parameter instantiated with the anonymous lifetime #2 defined here
7+
note: lifetime parameter instantiated with the anonymous lifetime as defined here
88
--> $DIR/issue-87748.rs:18:5
99
|
1010
LL | fn do_sth(_: u32) {}
1111
| ^^^^^^^^^^^^^^^^^
12-
note: but lifetime parameter must outlive the anonymous lifetime #1 defined here
12+
note: but lifetime parameter must outlive the anonymous lifetime as defined here
1313
--> $DIR/issue-87748.rs:18:5
1414
|
1515
LL | fn do_sth(_: u32) {}

src/test/ui/generic-associated-types/issue-95305.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33
// at some point in the future.
44

55
#![feature(generic_associated_types)]
6-
6+
#![feature(anonymous_lifetime_in_impl_trait)]
77
trait Foo {
88
type Item<'a>;
99
}
1010

1111
fn foo(x: &impl Foo<Item<'_> = u32>) { }
1212
//~^ ERROR `'_` cannot be used here [E0637]
1313

14+
// Ok: the anonymous lifetime is bound to the function.
1415
fn bar(x: &impl for<'a> Foo<Item<'a> = &'_ u32>) { }
15-
//~^ ERROR missing lifetime specifier
16+
17+
// Ok: the anonymous lifetime is bound to the function.
18+
fn baz(x: &impl for<'a> Foo<Item<'a> = &u32>) { }
1619

1720
fn main() {}

src/test/ui/generic-associated-types/issue-95305.stderr

+2-14
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,6 @@ error[E0637]: `'_` cannot be used here
44
LL | fn foo(x: &impl Foo<Item<'_> = u32>) { }
55
| ^^ `'_` is a reserved lifetime name
66

7-
error[E0106]: missing lifetime specifier
8-
--> $DIR/issue-95305.rs:14:41
9-
|
10-
LL | fn bar(x: &impl for<'a> Foo<Item<'a> = &'_ u32>) { }
11-
| ^^ expected named lifetime parameter
12-
|
13-
help: consider using the `'a` lifetime
14-
|
15-
LL | fn bar(x: &impl for<'a> Foo<Item<'a> = &'a u32>) { }
16-
| ~~
17-
18-
error: aborting due to 2 previous errors
7+
error: aborting due to previous error
198

20-
Some errors have detailed explanations: E0106, E0637.
21-
For more information about an error, try `rustc --explain E0106`.
9+
For more information about this error, try `rustc --explain E0637`.

src/test/ui/issues/issue-37884.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LL | fn next(&'a mut self) -> Option<Self::Item>
66
|
77
= note: expected fn pointer `fn(&mut RepeatMut<'a, T>) -> Option<_>`
88
found fn pointer `fn(&'a mut RepeatMut<'a, T>) -> Option<_>`
9-
note: the anonymous lifetime #1 defined here...
9+
note: the anonymous lifetime as defined here...
1010
--> $DIR/issue-37884.rs:6:5
1111
|
1212
LL | fn next(&'a mut self) -> Option<Self::Item>

src/test/ui/nll/ty-outlives/impl-trait-captures.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
22
--> $DIR/impl-trait-captures.rs:11:5
33
|
44
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
5-
| -- hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrAnon(0)) T` captures the anonymous lifetime defined here
5+
| -- hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_)) T` captures the anonymous lifetime defined here
66
LL | x
77
| ^
88
|
9-
help: to declare that the `impl Trait` captures `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrAnon(0))`, you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrAnon(0))` lifetime bound
9+
help: to declare that the `impl Trait` captures `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_))`, you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_))` lifetime bound
1010
|
11-
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrAnon(0)) {
12-
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11+
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_)) {
12+
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1313

1414
error: aborting due to previous error
1515

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// edition:2021
2+
// gate-test-anonymous_lifetime_in_impl_trait
3+
// Verify the behaviour of `feature(anonymous_lifetime_in_impl_trait)`.
4+
5+
fn f(_: impl Iterator<Item = &'_ ()>) {}
6+
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
7+
8+
fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
9+
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
10+
//~| ERROR missing lifetime specifier
11+
12+
// Anonymous lifetimes in async fn are already allowed.
13+
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
14+
async fn h(_: impl Iterator<Item = &'_ ()>) {}
15+
16+
// Anonymous lifetimes in async fn are already allowed.
17+
// But that lifetime does not participate in resolution.
18+
async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
19+
//~^ ERROR missing lifetime specifier
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
2+
--> $DIR/impl-trait-missing-lifetime-gated.rs:5:31
3+
|
4+
LL | fn f(_: impl Iterator<Item = &'_ ()>) {}
5+
| ^^
6+
|
7+
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
8+
9+
error[E0106]: missing lifetime specifier
10+
--> $DIR/impl-trait-missing-lifetime-gated.rs:8:50
11+
|
12+
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
13+
| ^^ expected named lifetime parameter
14+
|
15+
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
16+
help: consider using the `'static` lifetime
17+
|
18+
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
19+
| ~~~~~~~
20+
21+
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
22+
--> $DIR/impl-trait-missing-lifetime-gated.rs:8:31
23+
|
24+
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
25+
| ^^
26+
|
27+
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
28+
29+
error[E0106]: missing lifetime specifier
30+
--> $DIR/impl-trait-missing-lifetime-gated.rs:18:56
31+
|
32+
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
33+
| ^^ expected named lifetime parameter
34+
|
35+
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
36+
help: consider using the `'static` lifetime
37+
|
38+
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
39+
| ~~~~~~~
40+
41+
error: aborting due to 4 previous errors
42+
43+
Some errors have detailed explanations: E0106, E0658.
44+
For more information about an error, try `rustc --explain E0106`.
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,19 @@
1-
fn f(_: impl Iterator<Item = &'_ ()>) {} //~ ERROR missing lifetime specifier
1+
// edition:2021
2+
3+
#![feature(anonymous_lifetime_in_impl_trait)]
4+
5+
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
6+
fn f(_: impl Iterator<Item = &'_ ()>) {}
7+
8+
// But that lifetime does not participate in resolution.
9+
fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
10+
//~^ ERROR missing lifetime specifier
11+
12+
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
13+
async fn h(_: impl Iterator<Item = &'_ ()>) {}
14+
15+
// But that lifetime does not participate in resolution.
16+
async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
17+
//~^ ERROR missing lifetime specifier
18+
219
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
error[E0106]: missing lifetime specifier
2-
--> $DIR/impl-trait-missing-lifetime.rs:1:31
2+
--> $DIR/impl-trait-missing-lifetime.rs:9:50
33
|
4-
LL | fn f(_: impl Iterator<Item = &'_ ()>) {}
5-
| ^^ expected named lifetime parameter
4+
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
5+
| ^^ expected named lifetime parameter
66
|
7-
help: consider introducing a named lifetime parameter
7+
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
8+
help: consider using the `'static` lifetime
89
|
9-
LL | fn f<'a>(_: impl Iterator<Item = &'a ()>) {}
10-
| ++++ ~~
10+
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
11+
| ~~~~~~~
1112

12-
error: aborting due to previous error
13+
error[E0106]: missing lifetime specifier
14+
--> $DIR/impl-trait-missing-lifetime.rs:16:56
15+
|
16+
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
17+
| ^^ expected named lifetime parameter
18+
|
19+
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
20+
help: consider using the `'static` lifetime
21+
|
22+
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
23+
| ~~~~~~~
24+
25+
error: aborting due to 2 previous errors
1326

1427
For more information about this error, try `rustc --explain E0106`.

src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ note: because this has an unmet lifetime requirement
2121
|
2222
LL | pub struct Wrapper<T: Trait>(T);
2323
| ^^^^^ introduces a `'static` lifetime requirement
24-
note: the anonymous lifetime #1 defined here...
25-
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:5
24+
note: the anonymous lifetime as defined here...
25+
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:29
2626
|
2727
LL | pub fn repro(_: Wrapper<Ref>);
28-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
28+
| ^^^
2929
note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
3030
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:1
3131
|

src/tools/clippy/clippy_lints/src/inherent_to_string.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
22
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
33
use clippy_utils::{get_trait_def_id, paths, return_ty, trait_ref_of_method};
44
use if_chain::if_chain;
5-
use rustc_hir::{ImplItem, ImplItemKind};
5+
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind};
66
use rustc_lint::{LateContext, LateLintPass};
77
use rustc_session::{declare_lint_pass, declare_tool_lint};
88
use rustc_span::sym;
@@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
102102
let decl = &signature.decl;
103103
if decl.implicit_self.has_implicit_self();
104104
if decl.inputs.len() == 1;
105-
if impl_item.generics.params.is_empty();
105+
if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
106106

107107
// Check if return type is String
108108
if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String);

src/tools/clippy/clippy_lints/src/lifetimes.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use rustc_hir::intravisit::{
99
use rustc_hir::FnRetTy::Return;
1010
use rustc_hir::{
1111
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
12-
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin,
13-
TraitBoundModifier, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
12+
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, LifetimeParamKind, ParamName, PolyTraitRef,
13+
PredicateOrigin, TraitBoundModifier, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
1414
};
1515
use rustc_lint::{LateContext, LateLintPass};
1616
use rustc_middle::hir::nested_filter as middle_nested_filter;
@@ -338,7 +338,10 @@ fn could_use_elision<'tcx>(
338338
fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<RefLt> {
339339
let mut allowed_lts = FxHashSet::default();
340340
for par in named_generics.iter() {
341-
if let GenericParamKind::Lifetime { .. } = par.kind {
341+
if let GenericParamKind::Lifetime {
342+
kind: LifetimeParamKind::Explicit,
343+
} = par.kind
344+
{
342345
allowed_lts.insert(RefLt::Named(par.name.ident().name));
343346
}
344347
}
@@ -379,6 +382,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
379382
self.lts.push(RefLt::Static);
380383
} else if let LifetimeName::Param(_, ParamName::Fresh) = lt.name {
381384
// Fresh lifetimes generated should be ignored.
385+
self.lts.push(RefLt::Unnamed);
382386
} else if lt.is_elided() {
383387
self.lts.push(RefLt::Unnamed);
384388
} else {

src/tools/clippy/clippy_lints/src/ptr.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -495,12 +495,13 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
495495
if let FnRetTy::Return(ty) = sig.decl.output
496496
&& let Some((out, Mutability::Mut, _)) = get_rptr_lm(ty)
497497
{
498+
let out_region = cx.tcx.named_region(out.hir_id);
498499
let args: Option<Vec<_>> = sig
499500
.decl
500501
.inputs
501502
.iter()
502503
.filter_map(get_rptr_lm)
503-
.filter(|&(lt, _, _)| lt.name == out.name)
504+
.filter(|&(lt, _, _)| cx.tcx.named_region(lt.hir_id) == out_region)
504505
.map(|(_, mutability, span)| (mutability == Mutability::Not).then(|| span))
505506
.collect();
506507
if let Some(args) = args

0 commit comments

Comments
 (0)