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
This commit is contained in:
bors 2018-06-21 23:08:32 +00:00
commit ec60dd81f9
7 changed files with 87 additions and 14 deletions

View File

@ -434,8 +434,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
instantiated_ty: Ty<'gcx>,
) -> Ty<'gcx> {
debug!(
"infer_anon_definition_from_instantiation(instantiated_ty={:?})",
instantiated_ty
"infer_anon_definition_from_instantiation(def_id={:?}, instantiated_ty={:?})",
def_id, instantiated_ty
);
let gcx = self.tcx.global_tcx();

View File

@ -638,8 +638,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// and ban them. Type variables instantiated inside binders aren't
// well-supported at the moment, so this doesn't work.
// In the future, this should be fixed and this error should be removed.
let def = self.map.defs.get(&lifetime.id);
if let Some(&Region::LateBound(_, def_id, _)) = def {
let def = self.map.defs.get(&lifetime.id).cloned();
if let Some(Region::LateBound(_, def_id, _)) = def {
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
// Ensure that the parent of the def is an item, not HRTB
let parent_id = self.tcx.hir.get_parent_node(node_id);
@ -657,6 +657,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
"`impl Trait` can only capture lifetimes \
bound at the fn or impl level"
);
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
}
}
}
@ -2453,6 +2454,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
}
}
/// Sometimes we resolve a lifetime, but later find that it is an
/// error (esp. around impl trait). In that case, we remove the
/// entry into `map.defs` so as not to confuse later code.
fn uninsert_lifetime_on_error(&mut self, lifetime_ref: &'tcx hir::Lifetime, bad_def: Region) {
let old_value = self.map.defs.remove(&lifetime_ref.id);
assert_eq!(old_value, Some(bad_def));
}
}
///////////////////////////////////////////////////////////////////////////

View File

@ -1066,7 +1066,24 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ItemExistential(hir::ExistTy { impl_trait_fn: None, .. }) => unimplemented!(),
// existential types desugared from impl Trait
ItemExistential(hir::ExistTy { impl_trait_fn: Some(owner), .. }) => {
tcx.typeck_tables_of(owner).concrete_existential_types[&def_id]
tcx.typeck_tables_of(owner).concrete_existential_types
.get(&def_id)
.cloned()
.unwrap_or_else(|| {
// This can occur if some error in the
// owner fn prevented us from populating
// the `concrete_existential_types` table.
tcx.sess.delay_span_bug(
DUMMY_SP,
&format!(
"owner {:?} has no existential type for {:?} in its tables",
owner,
def_id,
),
);
tcx.types.err
})
},
ItemTrait(..) | ItemTraitAlias(..) |
ItemMod(..) |

View File

@ -19,7 +19,7 @@ fn free_fn_capture_hrtb_in_impl_trait()
-> Box<for<'a> Id<impl Lt<'a>>>
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657]
{
()
() //~ ERROR mismatched types
}
struct Foo;
@ -28,7 +28,7 @@ impl Foo {
-> Box<for<'a> Id<impl Lt<'a>>>
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
{
()
() //~ ERROR mismatched types
}
}

View File

@ -10,6 +10,25 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl le
LL | -> Box<for<'a> Id<impl Lt<'a>>>
| ^^
error: aborting due to 2 previous errors
error[E0308]: mismatched types
--> $DIR/E0657.rs:22:5
|
LL | () //~ ERROR mismatched types
| ^^ expected struct `std::boxed::Box`, found ()
|
= note: expected type `std::boxed::Box<Id<_> + 'static>`
found type `()`
For more information about this error, try `rustc --explain E0657`.
error[E0308]: mismatched types
--> $DIR/E0657.rs:31:9
|
LL | () //~ ERROR mismatched types
| ^^ expected struct `std::boxed::Box`, found ()
|
= note: expected type `std::boxed::Box<Id<_> + 'static>`
found type `()`
error: aborting due to 4 previous errors
Some errors occurred: E0308, E0657.
For more information about an error, try `rustc --explain E0308`.

View File

@ -34,8 +34,9 @@ fn projection_with_named_trait_is_disallowed(x: impl Iterator)
fn projection_with_named_trait_inside_path_is_disallowed()
-> <::std::ops::Range<impl Debug> as Iterator>::Item
//~^ ERROR `impl Trait` is not allowed in path parameters
{
(1i32..100).next().unwrap()
//~| ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
{ //~ ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
(1i32..100).next().unwrap() //~ ERROR mismatched types
}
fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()

View File

@ -17,7 +17,7 @@ LL | -> <::std::ops::Range<impl Debug> as Iterator>::Item
| ^^^^^^^^^^
error[E0667]: `impl Trait` is not allowed in path parameters
--> $DIR/impl_trait_projections.rs:42:29
--> $DIR/impl_trait_projections.rs:43:29
|
LL | -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
| ^^^^^^^^^^
@ -30,7 +30,34 @@ LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
= note: specify the type using the syntax `<impl std::iter::Iterator as Trait>::Item`
error: aborting due to 5 previous errors
error[E0277]: the trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
--> $DIR/impl_trait_projections.rs:38:1
|
LL | / { //~ ERROR trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
LL | | (1i32..100).next().unwrap() //~ ERROR mismatched types
LL | | }
| |_^ the trait `std::iter::Step` is not implemented for `impl std::fmt::Debug`
|
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<impl std::fmt::Debug>`
Some errors occurred: E0223, E0667.
error[E0308]: mismatched types
--> $DIR/impl_trait_projections.rs:39:5
|
LL | (1i32..100).next().unwrap() //~ ERROR mismatched types
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected anonymized type, found i32
|
= note: expected type `impl std::fmt::Debug`
found type `i32`
error[E0277]: the trait bound `impl std::fmt::Debug: std::iter::Step` is not satisfied
--> $DIR/impl_trait_projections.rs:35:8
|
LL | -> <::std::ops::Range<impl Debug> as Iterator>::Item
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `impl std::fmt::Debug`
|
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<impl std::fmt::Debug>`
error: aborting due to 8 previous errors
Some errors occurred: E0223, E0277, E0308, E0667.
For more information about an error, try `rustc --explain E0223`.