Skip to content

Commit ec60dd8

Browse files
committed
Auto merge of #51690 - nikomatsakis:issue-51683-existential-fail, r=oli-obk
do not ICE when existing type info is incomplete Apparently master is kinda ICE-y right now, but only for some people (sadly that set includes me). I'm not crazy about this PR, because it seems to regress diagnostics a lot, but it *does* fix the problems. I think probably fixing the diagnostics should be done by doing a better job of suppressing errors? Mitigates #51683 r? @oli-obk
2 parents 662c70a + e3fa2d5 commit ec60dd8

File tree

7 files changed

+87
-14
lines changed

7 files changed

+87
-14
lines changed

src/librustc/infer/anon_types/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
434434
instantiated_ty: Ty<'gcx>,
435435
) -> Ty<'gcx> {
436436
debug!(
437-
"infer_anon_definition_from_instantiation(instantiated_ty={:?})",
438-
instantiated_ty
437+
"infer_anon_definition_from_instantiation(def_id={:?}, instantiated_ty={:?})",
438+
def_id, instantiated_ty
439439
);
440440

441441
let gcx = self.tcx.global_tcx();

src/librustc/middle/resolve_lifetime.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -638,8 +638,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
638638
// and ban them. Type variables instantiated inside binders aren't
639639
// well-supported at the moment, so this doesn't work.
640640
// In the future, this should be fixed and this error should be removed.
641-
let def = self.map.defs.get(&lifetime.id);
642-
if let Some(&Region::LateBound(_, def_id, _)) = def {
641+
let def = self.map.defs.get(&lifetime.id).cloned();
642+
if let Some(Region::LateBound(_, def_id, _)) = def {
643643
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
644644
// Ensure that the parent of the def is an item, not HRTB
645645
let parent_id = self.tcx.hir.get_parent_node(node_id);
@@ -657,6 +657,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
657657
"`impl Trait` can only capture lifetimes \
658658
bound at the fn or impl level"
659659
);
660+
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
660661
}
661662
}
662663
}
@@ -2453,6 +2454,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
24532454
}
24542455
}
24552456
}
2457+
2458+
/// Sometimes we resolve a lifetime, but later find that it is an
2459+
/// error (esp. around impl trait). In that case, we remove the
2460+
/// entry into `map.defs` so as not to confuse later code.
2461+
fn uninsert_lifetime_on_error(&mut self, lifetime_ref: &'tcx hir::Lifetime, bad_def: Region) {
2462+
let old_value = self.map.defs.remove(&lifetime_ref.id);
2463+
assert_eq!(old_value, Some(bad_def));
2464+
}
24562465
}
24572466

24582467
///////////////////////////////////////////////////////////////////////////

src/librustc_typeck/collect.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,24 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
10661066
ItemExistential(hir::ExistTy { impl_trait_fn: None, .. }) => unimplemented!(),
10671067
// existential types desugared from impl Trait
10681068
ItemExistential(hir::ExistTy { impl_trait_fn: Some(owner), .. }) => {
1069-
tcx.typeck_tables_of(owner).concrete_existential_types[&def_id]
1069+
tcx.typeck_tables_of(owner).concrete_existential_types
1070+
.get(&def_id)
1071+
.cloned()
1072+
.unwrap_or_else(|| {
1073+
// This can occur if some error in the
1074+
// owner fn prevented us from populating
1075+
// the `concrete_existential_types` table.
1076+
tcx.sess.delay_span_bug(
1077+
DUMMY_SP,
1078+
&format!(
1079+
"owner {:?} has no existential type for {:?} in its tables",
1080+
owner,
1081+
def_id,
1082+
),
1083+
);
1084+
1085+
tcx.types.err
1086+
})
10701087
},
10711088
ItemTrait(..) | ItemTraitAlias(..) |
10721089
ItemMod(..) |

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn free_fn_capture_hrtb_in_impl_trait()
1919
-> Box<for<'a> Id<impl Lt<'a>>>
2020
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657]
2121
{
22-
()
22+
() //~ ERROR mismatched types
2323
}
2424

2525
struct Foo;
@@ -28,7 +28,7 @@ impl Foo {
2828
-> Box<for<'a> Id<impl Lt<'a>>>
2929
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
3030
{
31-
()
31+
() //~ ERROR mismatched types
3232
}
3333
}
3434

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

+21-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,25 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl le
1010
LL | -> Box<for<'a> Id<impl Lt<'a>>>
1111
| ^^
1212

13-
error: aborting due to 2 previous errors
13+
error[E0308]: mismatched types
14+
--> $DIR/E0657.rs:22:5
15+
|
16+
LL | () //~ ERROR mismatched types
17+
| ^^ expected struct `std::boxed::Box`, found ()
18+
|
19+
= note: expected type `std::boxed::Box<Id<_> + 'static>`
20+
found type `()`
21+
22+
error[E0308]: mismatched types
23+
--> $DIR/E0657.rs:31:9
24+
|
25+
LL | () //~ ERROR mismatched types
26+
| ^^ expected struct `std::boxed::Box`, found ()
27+
|
28+
= note: expected type `std::boxed::Box<Id<_> + 'static>`
29+
found type `()`
30+
31+
error: aborting due to 4 previous errors
1432

15-
For more information about this error, try `rustc --explain E0657`.
33+
Some errors occurred: E0308, E0657.
34+
For more information about an error, try `rustc --explain E0308`.

src/test/ui/impl_trait_projections.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ fn projection_with_named_trait_is_disallowed(x: impl Iterator)
3434
fn projection_with_named_trait_inside_path_is_disallowed()
3535
-> <::std::ops::Range<impl Debug> as Iterator>::Item
3636
//~^ ERROR `impl Trait` is not allowed in path parameters
37-
{
38-
(1i32..100).next().unwrap()
37+
//~| ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
38+
{ //~ ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
39+
(1i32..100).next().unwrap() //~ ERROR mismatched types
3940
}
4041

4142
fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()

src/test/ui/impl_trait_projections.stderr

+30-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ LL | -> <::std::ops::Range<impl Debug> as Iterator>::Item
1717
| ^^^^^^^^^^
1818

1919
error[E0667]: `impl Trait` is not allowed in path parameters
20-
--> $DIR/impl_trait_projections.rs:42:29
20+
--> $DIR/impl_trait_projections.rs:43:29
2121
|
2222
LL | -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
2323
| ^^^^^^^^^^
@@ -30,7 +30,34 @@ LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
3030
|
3131
= note: specify the type using the syntax `<impl std::iter::Iterator as Trait>::Item`
3232

33-
error: aborting due to 5 previous errors
33+
error[E0277]: the trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
34+
--> $DIR/impl_trait_projections.rs:38:1
35+
|
36+
LL | / { //~ ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
37+
LL | | (1i32..100).next().unwrap() //~ ERROR mismatched types
38+
LL | | }
39+
| |_^ the trait `std::iter::Step` is not implemented for `impl std::fmt::Debug`
40+
|
41+
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<impl std::fmt::Debug>`
42+
43+
error[E0308]: mismatched types
44+
--> $DIR/impl_trait_projections.rs:39:5
45+
|
46+
LL | (1i32..100).next().unwrap() //~ ERROR mismatched types
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected anonymized type, found i32
48+
|
49+
= note: expected type `impl std::fmt::Debug`
50+
found type `i32`
51+
52+
error[E0277]: the trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
53+
--> $DIR/impl_trait_projections.rs:35:8
54+
|
55+
LL | -> <::std::ops::Range<impl Debug> as Iterator>::Item
56+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `impl std::fmt::Debug`
57+
|
58+
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<impl std::fmt::Debug>`
59+
60+
error: aborting due to 8 previous errors
3461

35-
Some errors occurred: E0223, E0667.
62+
Some errors occurred: E0223, E0277, E0308, E0667.
3663
For more information about an error, try `rustc --explain E0223`.

0 commit comments

Comments
 (0)