From 692f63803683534ca7ff1c0a0a5e15cbfc61db0a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 13 Jul 2021 15:05:29 +0000 Subject: [PATCH 1/3] Fix VecMap Extend impl --- compiler/rustc_data_structures/src/vec_map.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs index 73b04d3329cb8..1786fa340cc8b 100644 --- a/compiler/rustc_data_structures/src/vec_map.rs +++ b/compiler/rustc_data_structures/src/vec_map.rs @@ -127,13 +127,15 @@ impl IntoIterator for VecMap { } } -impl Extend<(K, V)> for VecMap { +impl Extend<(K, V)> for VecMap { fn extend>(&mut self, iter: I) { - self.0.extend(iter); + for (k, v) in iter { + self.insert(k, v); + } } - fn extend_one(&mut self, item: (K, V)) { - self.0.extend_one(item); + fn extend_one(&mut self, (k, v): (K, V)) { + self.insert(k, v); } fn extend_reserve(&mut self, additional: usize) { From 95f296db63d58f82a6a96d8b7baf52efaa26b260 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 13 Jul 2021 15:06:09 +0000 Subject: [PATCH 2/3] Debug log all the things --- compiler/rustc_typeck/src/collect/type_of.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index ee84974cb73c2..cfe1a2f56f451 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -509,11 +509,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } } +#[instrument(skip(tcx), level = "debug")] fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { use rustc_hir::{Expr, ImplItem, Item, TraitItem}; - debug!("find_opaque_ty_constraints({:?})", def_id); - struct ConstraintLocator<'tcx> { tcx: TyCtxt<'tcx>, def_id: DefId, @@ -522,13 +521,11 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } impl ConstraintLocator<'_> { + #[instrument(skip(self), level = "debug")] fn check(&mut self, def_id: LocalDefId) { // Don't try to check items that cannot possibly constrain the type. if !self.tcx.has_typeck_results(def_id) { - debug!( - "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`: no typeck results", - self.def_id, def_id, - ); + debug!("no constraint: no typeck results"); return; } // Calling `mir_borrowck` can lead to cycle errors through @@ -540,10 +537,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { .get_by(|(key, _)| key.def_id == self.def_id) .is_none() { - debug!( - "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`", - self.def_id, def_id, - ); + debug!("no constraints in typeck results"); return; } // Use borrowck to get the type with unerased regions. @@ -603,7 +597,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { if let Some((prev_span, prev_ty)) = self.found { if *concrete_type != prev_ty { - debug!("find_opaque_ty_constraints: span={:?}", span); + debug!(?span); // Found different concrete types for the opaque type. let mut err = self.tcx.sess.struct_span_err( span, From 587e8fd11267911599322878fb37c8d185738c9b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 13 Jul 2021 15:19:35 +0000 Subject: [PATCH 3/3] Loop over all opaque types instead of looking at just the first one with the same DefId --- compiler/rustc_typeck/src/collect/type_of.rs | 20 ++++++++----------- .../ui/type-alias-impl-trait/issue-85113.rs | 1 + .../type-alias-impl-trait/issue-85113.stderr | 14 ++++++++++++- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index cfe1a2f56f451..7b0002914eca8 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -542,13 +542,14 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } // Use borrowck to get the type with unerased regions. let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types; - if let Some((opaque_type_key, concrete_type)) = - concrete_opaque_types.iter().find(|(key, _)| key.def_id == self.def_id) - { - debug!( - "find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}", - self.def_id, def_id, concrete_type, - ); + debug!(?concrete_opaque_types); + for (opaque_type_key, concrete_type) in concrete_opaque_types { + if opaque_type_key.def_id != self.def_id { + // Ignore constraints for other opaque types. + continue; + } + + debug!(?concrete_type, ?opaque_type_key.substs, "found constraint"); // FIXME(oli-obk): trace the actual span from inference to improve errors. let span = self.tcx.def_span(def_id); @@ -613,11 +614,6 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } else { self.found = Some((span, concrete_type)); } - } else { - debug!( - "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`", - self.def_id, def_id, - ); } } } diff --git a/src/test/ui/type-alias-impl-trait/issue-85113.rs b/src/test/ui/type-alias-impl-trait/issue-85113.rs index b09833f3ed014..0c37399df8dd2 100644 --- a/src/test/ui/type-alias-impl-trait/issue-85113.rs +++ b/src/test/ui/type-alias-impl-trait/issue-85113.rs @@ -12,6 +12,7 @@ trait Output<'a> {} impl<'a> Output<'a> for &'a str {} fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> { + //~^ ERROR: concrete type differs from previous defining opaque type use let out: OpaqueOutputImpl<'a> = arg; arg } diff --git a/src/test/ui/type-alias-impl-trait/issue-85113.stderr b/src/test/ui/type-alias-impl-trait/issue-85113.stderr index 361d66866ef8b..233c996340d84 100644 --- a/src/test/ui/type-alias-impl-trait/issue-85113.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-85113.stderr @@ -10,6 +10,18 @@ note: hidden type `&' str` captures lifetime smaller than the function bo LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a; | ^^^^^^^^^^^^^^^^^^^^ +error: concrete type differs from previous defining opaque type use + --> $DIR/issue-85113.rs:14:1 + | +LL | fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&' str`, got `&'a str` + | +note: previous use here + --> $DIR/issue-85113.rs:14:1 + | +LL | fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0477]: the type `&' str` does not fulfill the required lifetime --> $DIR/issue-85113.rs:5:29 | @@ -42,7 +54,7 @@ LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a; = note: expected `Output<'a>` found `Output<'_>` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0477, E0495, E0700. For more information about an error, try `rustc --explain E0477`.