Skip to content

Commit 00b8189

Browse files
committed
Suppress
1 parent 9ae765d commit 00b8189

7 files changed

Lines changed: 108 additions & 4 deletions

File tree

compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! where one region is named and the other is anonymous.
33
44
use rustc_errors::Diag;
5+
use rustc_middle::ty;
56
use tracing::debug;
67

78
use crate::error_reporting::infer::nice_region_error::NiceRegionError;
@@ -72,16 +73,34 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
7273
{
7374
return None;
7475
}
76+
let orig_ty = anon_param_info.orig_param_ty;
77+
// Don't suggest naming the outer lifetime when it already appears in the pointee
78+
// (e.g. `&'a mut Buffer<'a>`); point at borrow splitting instead.
79+
let suggestion_would_alias_lifetime =
80+
if let ty::Ref(_, orig_inner_ty, ty::Mutability::Mut) = orig_ty.kind() {
81+
self.tcx().any_free_region_meets(orig_inner_ty, |r| r == named)
82+
} else {
83+
false
84+
};
85+
7586
let named = named.to_string();
87+
let new_ty_span = if suggestion_would_alias_lifetime { None } else { Some(new_ty_span) };
7688
let err = match param.pat.simple_ident() {
7789
Some(simple_ident) => ExplicitLifetimeRequired::WithIdent {
7890
span,
7991
simple_ident,
8092
named,
8193
new_ty_span,
8294
new_ty,
95+
link_nomicon: suggestion_would_alias_lifetime,
96+
},
97+
None => ExplicitLifetimeRequired::WithParamType {
98+
span,
99+
named,
100+
new_ty_span,
101+
new_ty,
102+
link_nomicon: suggestion_would_alias_lifetime,
83103
},
84-
None => ExplicitLifetimeRequired::WithParamType { span, named, new_ty_span, new_ty },
85104
};
86105
Some(self.tcx().sess.dcx().create_err(err))
87106
}

compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pub struct AnonymousParamInfo<'tcx> {
1616
pub param: &'tcx hir::Param<'tcx>,
1717
/// The type corresponding to the anonymous region parameter.
1818
pub param_ty: Ty<'tcx>,
19+
/// The original type before region replacement.
20+
pub orig_param_ty: Ty<'tcx>,
1921
/// The `ty::LateParamRegionKind` corresponding to the anonymous region.
2022
pub kind: ty::LateParamRegionKind,
2123
/// The `Span` of the parameter type.
@@ -94,7 +96,14 @@ pub fn find_param_with_region<'tcx>(
9496
let ty_hir_id = fn_decl.inputs[index].hir_id;
9597
let param_ty_span = tcx.hir_span(ty_hir_id);
9698
let is_first = index == 0;
97-
AnonymousParamInfo { param, param_ty: new_param_ty, param_ty_span, kind, is_first }
99+
AnonymousParamInfo {
100+
param,
101+
param_ty: new_param_ty,
102+
orig_param_ty: ty,
103+
param_ty_span,
104+
kind,
105+
is_first,
106+
}
98107
})
99108
})
100109
}

compiler/rustc_trait_selection/src/errors.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -868,8 +868,13 @@ pub(crate) enum ExplicitLifetimeRequired<'a> {
868868
applicability = "unspecified",
869869
style = "verbose"
870870
)]
871-
new_ty_span: Span,
871+
new_ty_span: Option<Span>,
872872
new_ty: Ty<'a>,
873+
#[help(
874+
"see <https://doc.rust-lang.org/nomicon/borrow-splitting.html> \
875+
for more information about lifetime errors related to mutable references"
876+
)]
877+
link_nomicon: bool,
873878
},
874879
#[diag("explicit lifetime required in parameter type", code = E0621)]
875880
WithParamType {
@@ -883,8 +888,13 @@ pub(crate) enum ExplicitLifetimeRequired<'a> {
883888
applicability = "unspecified",
884889
style = "verbose"
885890
)]
886-
new_ty_span: Span,
891+
new_ty_span: Option<Span>,
887892
new_ty: Ty<'a>,
893+
#[help(
894+
"see <https://doc.rust-lang.org/nomicon/borrow-splitting.html> \
895+
for more information about lifetime errors related to mutable references"
896+
)]
897+
link_nomicon: bool,
888898
},
889899
}
890900

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Regression test for #156682
2+
// When the suggested type would NOT alias the outer reference's lifetime with one
3+
// already used inside the pointee, the normal suggestion should still apply.
4+
5+
pub fn push<'a>(x: &mut Vec<&'a u8>, y: &u8) {
6+
x.push(y);
7+
//~^ ERROR explicit lifetime required in the type of `y`
8+
}
9+
10+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0621]: explicit lifetime required in the type of `y`
2+
--> $DIR/e0621-mut-ref-aliases-pointee-lifetime-distinct.rs:6:5
3+
|
4+
LL | x.push(y);
5+
| ^^^^^^^^^ lifetime `'a` required
6+
|
7+
help: add explicit lifetime `'a` to the type of `y`
8+
|
9+
LL | pub fn push<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
10+
| ++
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0621`.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Regression test for #156682
2+
// E0621 should not suggest `&'a mut Buffer<'a>`, which would alias the outer
3+
// reference's lifetime with one already used inside the pointee.
4+
5+
pub struct Buffer<'a> {
6+
buf: &'a mut [u8],
7+
}
8+
9+
pub fn foo<'a>(buffer: &mut Buffer<'a>) {
10+
buffer.buf = &mut buffer.buf[..];
11+
//~^ ERROR explicit lifetime required in the type of `buffer`
12+
}
13+
14+
pub struct Wrapper<'a> {
15+
inner: Buffer<'a>,
16+
}
17+
18+
pub fn baz<'a>(wrapper: &mut Wrapper<'a>) {
19+
wrapper.inner.buf = &mut wrapper.inner.buf[..];
20+
//~^ ERROR explicit lifetime required in the type of `wrapper`
21+
}
22+
23+
fn main() {}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0621]: explicit lifetime required in the type of `buffer`
2+
--> $DIR/e0621-mut-ref-aliases-pointee-lifetime.rs:10:5
3+
|
4+
LL | buffer.buf = &mut buffer.buf[..];
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
6+
|
7+
= help: see <https://doc.rust-lang.org/nomicon/borrow-splitting.html> for more information about lifetime errors related to mutable references
8+
9+
error[E0621]: explicit lifetime required in the type of `wrapper`
10+
--> $DIR/e0621-mut-ref-aliases-pointee-lifetime.rs:19:5
11+
|
12+
LL | wrapper.inner.buf = &mut wrapper.inner.buf[..];
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
14+
|
15+
= help: see <https://doc.rust-lang.org/nomicon/borrow-splitting.html> for more information about lifetime errors related to mutable references
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0621`.

0 commit comments

Comments
 (0)