Skip to content

Commit 9acfbb2

Browse files
committed
Fix ICE in region naming.
This commit puts a fix in place for the ICE in region naming code so that it doesn't break the compiler. However, this results in the diagnostic being poorer as the borrow explanation that was causing the ICE is not being added - this should be fixed as a follow-up.
1 parent a8a1bf9 commit 9acfbb2

File tree

6 files changed

+96
-16
lines changed

6 files changed

+96
-16
lines changed

src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -271,13 +271,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
271271
borrow_region_vid,
272272
region,
273273
);
274-
let opt_place_desc = self.describe_place(&borrow.borrowed_place);
275-
BorrowExplanation::MustBeValidFor {
276-
category,
277-
from_closure,
278-
span,
279-
region_name,
280-
opt_place_desc,
274+
if let Some(region_name) = region_name {
275+
let opt_place_desc = self.describe_place(&borrow.borrowed_place);
276+
BorrowExplanation::MustBeValidFor {
277+
category,
278+
from_closure,
279+
span,
280+
region_name,
281+
opt_place_desc,
282+
}
283+
} else {
284+
BorrowExplanation::Unexplained
281285
}
282286
} else {
283287
BorrowExplanation::Unexplained

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
376376

377377
diag.span_label(span, message);
378378

379-
match self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, &mut 1)
380-
.source
381-
{
379+
match self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, &mut 1).unwrap().source {
382380
RegionNameSource::NamedEarlyBoundRegion(fr_span)
383381
| RegionNameSource::NamedFreeRegion(fr_span)
384382
| RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _)
@@ -521,10 +519,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
521519
);
522520

523521
let counter = &mut 1;
524-
let fr_name = self.give_region_a_name(infcx, mir, mir_def_id, fr, counter);
522+
let fr_name = self.give_region_a_name(infcx, mir, mir_def_id, fr, counter).unwrap();
525523
fr_name.highlight_region_name(&mut diag);
526524
let outlived_fr_name =
527-
self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, counter);
525+
self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, counter).unwrap();
528526
outlived_fr_name.highlight_region_name(&mut diag);
529527

530528
let mir_def_name = if infcx.tcx.is_closure(mir_def_id) {
@@ -661,7 +659,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
661659
infcx: &InferCtxt<'_, '_, 'tcx>,
662660
borrow_region: RegionVid,
663661
outlived_region: RegionVid,
664-
) -> (ConstraintCategory, bool, Span, RegionName) {
662+
) -> (ConstraintCategory, bool, Span, Option<RegionName>) {
665663
let (category, from_closure, span) =
666664
self.best_blame_constraint(mir, borrow_region, |r| r == outlived_region);
667665
let outlived_fr_name =

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
157157
mir_def_id: DefId,
158158
fr: RegionVid,
159159
counter: &mut usize,
160-
) -> RegionName {
160+
) -> Option<RegionName> {
161161
debug!("give_region_a_name(fr={:?}, counter={})", fr, counter);
162162

163163
assert!(self.universal_regions.is_universal_region(fr));
@@ -177,8 +177,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
177177
self.give_name_if_anonymous_region_appears_in_output(
178178
infcx, mir, mir_def_id, fr, counter,
179179
)
180-
})
181-
.unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr));
180+
});
182181

183182
debug!("give_region_a_name: gave name {:?}", value);
184183
value
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0597]: `s` does not live long enough
2+
--> $DIR/issue-55850.rs:38:16
3+
|
4+
LL | yield &s[..]
5+
| ^ borrowed value does not live long enough
6+
LL | })
7+
| - `s` dropped here while still borrowed
8+
9+
error[E0626]: borrow may still be in use when generator yields
10+
--> $DIR/issue-55850.rs:38:16
11+
|
12+
LL | yield &s[..]
13+
| -------^---- possible yield occurs here
14+
15+
error: aborting due to 2 previous errors
16+
17+
Some errors occurred: E0597, E0626.
18+
For more information about an error, try `rustc --explain E0597`.

src/test/ui/nll/issue-55850.rs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(unused_mut)]
12+
#![feature(generators, generator_trait)]
13+
14+
use std::ops::Generator;
15+
use std::ops::GeneratorState::Yielded;
16+
17+
pub struct GenIter<G>(G);
18+
19+
impl <G> Iterator for GenIter<G>
20+
where
21+
G: Generator,
22+
{
23+
type Item = G::Yield;
24+
25+
fn next(&mut self) -> Option<Self::Item> {
26+
unsafe {
27+
match self.0.resume() {
28+
Yielded(y) => Some(y),
29+
_ => None
30+
}
31+
}
32+
}
33+
}
34+
35+
fn bug<'a>() -> impl Iterator<Item = &'a str> {
36+
GenIter(move || {
37+
let mut s = String::new();
38+
yield &s[..]
39+
})
40+
}
41+
42+
fn main() {
43+
bug();
44+
}

src/test/ui/nll/issue-55850.stderr

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0597]: `s` does not live long enough
2+
--> $DIR/issue-55850.rs:38:16
3+
|
4+
LL | yield &s[..]
5+
| ^ borrowed value does not live long enough
6+
LL | })
7+
| - borrowed value only lives until here
8+
|
9+
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 35:8...
10+
--> $DIR/issue-55850.rs:35:8
11+
|
12+
LL | fn bug<'a>() -> impl Iterator<Item = &'a str> {
13+
| ^^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0597`.

0 commit comments

Comments
 (0)