about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_data_structures/src/vec_map.rs10
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs36
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-85113.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-85113.stderr14
4 files changed, 33 insertions, 28 deletions
diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs
index 73b04d3329c..1786fa340cc 100644
--- a/compiler/rustc_data_structures/src/vec_map.rs
+++ b/compiler/rustc_data_structures/src/vec_map.rs
@@ -127,13 +127,15 @@ impl<K, V> IntoIterator for VecMap<K, V> {
     }
 }
 
-impl<K, V> Extend<(K, V)> for VecMap<K, V> {
+impl<K: PartialEq, V> Extend<(K, V)> for VecMap<K, V> {
     fn extend<I: IntoIterator<Item = (K, V)>>(&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) {
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index ee84974cb73..7b0002914ec 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,21 +537,19 @@ 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.
             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);
@@ -603,7 +598,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,
@@ -619,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 b09833f3ed0..0c37399df8d 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 361d66866ef..233c996340d 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 `&'<empty> 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 `&'<empty> 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 `&'<empty> 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`.