Skip to content

Commit 991da05

Browse files
authored
Rollup merge of #74051 - yodaldevoid:issue_60814, r=nikomatsakis
disallow non-static lifetimes in const generics Disallow non-static lifetimes in const generics in order to to patch over an ICE caused when we encounter a non-static lifetime in a const generic during borrow checking. This restriction may be relaxed in the future, but we need more discussion before then, and in the meantime we should still deal with this ICE. Fixes issue #60814
2 parents 0897bc2 + c60a035 commit 991da05

File tree

8 files changed

+109
-0
lines changed

8 files changed

+109
-0
lines changed

src/librustc_error_codes/error_codes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ E0767: include_str!("./error_codes/E0767.md"),
453453
E0768: include_str!("./error_codes/E0768.md"),
454454
E0769: include_str!("./error_codes/E0769.md"),
455455
E0770: include_str!("./error_codes/E0770.md"),
456+
E0771: include_str!("./error_codes/E0771.md"),
456457
;
457458
// E0006, // merged with E0005
458459
// E0008, // cannot bind by-move into a pattern guard
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
A non-`'static` lifetime was used in a const generic. This is currently not
2+
allowed.
3+
4+
Erroneous code example:
5+
6+
```compile_fail,E0771
7+
#![feature(const_generics)]
8+
9+
fn function_with_str<'a, const STRING: &'a str>() {} // error!
10+
```
11+
12+
To fix this issue, the lifetime in the const generic need to be changed to
13+
`'static`:
14+
15+
```
16+
#![feature(const_generics)]
17+
18+
fn function_with_str<const STRING: &'static str>() {} // ok!
19+
```
20+
21+
For more information, see [GitHub issue #74052].
22+
23+
[GitHub issue #74052]: https://github.com/rust-lang/rust/issues/74052

src/librustc_resolve/late/diagnostics.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,24 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
11411141
err.emit();
11421142
}
11431143

1144+
// FIXME(const_generics): This patches over a ICE caused by non-'static lifetimes in const
1145+
// generics. We are disallowing this until we can decide on how we want to handle non-'static
1146+
// lifetimes in const generics. See issue #74052 for discussion.
1147+
crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &hir::Lifetime) {
1148+
let mut err = struct_span_err!(
1149+
self.tcx.sess,
1150+
lifetime_ref.span,
1151+
E0771,
1152+
"use of non-static lifetime `{}` in const generic",
1153+
lifetime_ref
1154+
);
1155+
err.note(
1156+
"for more information, see issue #74052 \
1157+
<https://github.com/rust-lang/rust/issues/74052>",
1158+
);
1159+
err.emit();
1160+
}
1161+
11441162
crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool {
11451163
if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res {
11461164
if [

src/librustc_resolve/late/lifetimes.rs

+11
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ crate struct LifetimeContext<'a, 'tcx> {
173173
/// Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax.
174174
is_in_fn_syntax: bool,
175175

176+
is_in_const_generic: bool,
177+
176178
/// List of labels in the function/method currently under analysis.
177179
labels_in_fn: Vec<Ident>,
178180

@@ -333,6 +335,7 @@ fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap {
333335
scope: ROOT_SCOPE,
334336
trait_ref_hack: false,
335337
is_in_fn_syntax: false,
338+
is_in_const_generic: false,
336339
labels_in_fn: vec![],
337340
xcrate_object_lifetime_defaults: Default::default(),
338341
lifetime_uses: &mut Default::default(),
@@ -828,6 +831,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
828831
self.insert_lifetime(lifetime_ref, Region::Static);
829832
return;
830833
}
834+
if self.is_in_const_generic && lifetime_ref.name != LifetimeName::Error {
835+
self.emit_non_static_lt_in_const_generic_error(lifetime_ref);
836+
return;
837+
}
831838
self.resolve_lifetime_ref(lifetime_ref);
832839
}
833840

@@ -860,8 +867,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
860867
}
861868
}
862869
GenericParamKind::Const { ref ty, .. } => {
870+
let was_in_const_generic = self.is_in_const_generic;
871+
self.is_in_const_generic = true;
863872
walk_list!(self, visit_param_bound, param.bounds);
864873
self.visit_ty(&ty);
874+
self.is_in_const_generic = was_in_const_generic;
865875
}
866876
}
867877
}
@@ -1317,6 +1327,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
13171327
scope: &wrap_scope,
13181328
trait_ref_hack: self.trait_ref_hack,
13191329
is_in_fn_syntax: self.is_in_fn_syntax,
1330+
is_in_const_generic: self.is_in_const_generic,
13201331
labels_in_fn,
13211332
xcrate_object_lifetime_defaults,
13221333
lifetime_uses,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// run-pass
2+
3+
#![feature(const_generics)]
4+
//~^ WARN the feature `const_generics` is incomplete
5+
#![allow(dead_code)]
6+
7+
fn test<const N: usize>() {}
8+
9+
fn wow<'a>() -> &'a () {
10+
test::<{
11+
let _: &'a ();
12+
3
13+
}>();
14+
&()
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/const-argument-non-static-lifetime.rs:3:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
9+
10+
warning: 1 warning emitted
11+

src/test/ui/error-codes/E0771.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![feature(const_generics)]
2+
//~^ WARN the feature `const_generics` is incomplete
3+
4+
fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0771
5+
6+
fn main() {
7+
function_with_str::<"Hello, world!">()
8+
}

src/test/ui/error-codes/E0771.stderr

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/E0771.rs:1:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
9+
10+
error[E0771]: use of non-static lifetime `'a` in const generic
11+
--> $DIR/E0771.rs:4:41
12+
|
13+
LL | fn function_with_str<'a, const STRING: &'a str>() {}
14+
| ^^
15+
|
16+
= note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
17+
18+
error: aborting due to previous error; 1 warning emitted
19+
20+
For more information about this error, try `rustc --explain E0771`.

0 commit comments

Comments
 (0)