diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index f068a54ce44..5487da97d5b 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -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(); diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 091662966ea..f73e0ab2a9d 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -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)); + } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7a4fbc73c2e..4c849cad187 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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(..) | diff --git a/src/test/ui/error-codes/E0657.rs b/src/test/ui/error-codes/E0657.rs index c23aa40ee37..05a4b8b3544 100644 --- a/src/test/ui/error-codes/E0657.rs +++ b/src/test/ui/error-codes/E0657.rs @@ -19,7 +19,7 @@ fn free_fn_capture_hrtb_in_impl_trait() -> Box Id>> //~^ 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 Id>> //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level { - () + () //~ ERROR mismatched types } } diff --git a/src/test/ui/error-codes/E0657.stderr b/src/test/ui/error-codes/E0657.stderr index 737ae3a163a..23b9666de3c 100644 --- a/src/test/ui/error-codes/E0657.stderr +++ b/src/test/ui/error-codes/E0657.stderr @@ -10,6 +10,25 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl le LL | -> Box Id>> | ^^ -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 + '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 + '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`. diff --git a/src/test/ui/impl_trait_projections.rs b/src/test/ui/impl_trait_projections.rs index 57a0040600a..b64caccd98a 100644 --- a/src/test/ui/impl_trait_projections.rs +++ b/src/test/ui/impl_trait_projections.rs @@ -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 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() diff --git a/src/test/ui/impl_trait_projections.stderr b/src/test/ui/impl_trait_projections.stderr index f6d58984ece..b495d4b4b01 100644 --- a/src/test/ui/impl_trait_projections.stderr +++ b/src/test/ui/impl_trait_projections.stderr @@ -17,7 +17,7 @@ LL | -> <::std::ops::Range 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 | -> as Iterator>::Item | ^^^^^^^^^^ @@ -30,7 +30,34 @@ LL | fn projection_is_disallowed(x: impl Iterator) -> ::Item { | = note: specify the type using the syntax `::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` -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 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` + +error: aborting due to 8 previous errors + +Some errors occurred: E0223, E0277, E0308, E0667. For more information about an error, try `rustc --explain E0223`.