Skip to content

do not ICE when existing type info is incomplete #51690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/librustc/infer/anon_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
13 changes: 11 additions & 2 deletions src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,8 +632,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);
Expand All @@ -651,6 +651,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());
}
}
}
Expand Down Expand Up @@ -2377,6 +2378,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));
}
}

///////////////////////////////////////////////////////////////////////////
Expand Down
19 changes: 18 additions & 1 deletion src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,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(..) |
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/error-codes/E0657.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
}
}

Expand Down
23 changes: 21 additions & 2 deletions src/test/ui/error-codes/E0657.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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 `()`

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

For more information about this error, try `rustc --explain E0657`.
Some errors occurred: E0308, E0657.
For more information about an error, try `rustc --explain E0308`.
5 changes: 3 additions & 2 deletions src/test/ui/impl_trait_projections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
33 changes: 30 additions & 3 deletions src/test/ui/impl_trait_projections.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
| ^^^^^^^^^^
Expand All @@ -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>`

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, E0667.
Some errors occurred: E0223, E0277, E0308, E0667.
For more information about an error, try `rustc --explain E0223`.