|
1 | 1 | use rustc_data_structures::fx::FxHashMap; |
2 | 2 | use rustc_data_structures::vec_map::VecMap; |
| 3 | +use rustc_hir::def_id::DefId; |
3 | 4 | use rustc_hir::OpaqueTyOrigin; |
4 | 5 | use rustc_infer::infer::InferCtxt; |
5 | 6 | use rustc_middle::ty::subst::GenericArgKind; |
@@ -54,8 +55,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { |
54 | 55 | &self, |
55 | 56 | infcx: &InferCtxt<'_, 'tcx>, |
56 | 57 | opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, |
57 | | - ) -> VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> { |
58 | | - let mut result: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> = VecMap::new(); |
| 58 | + ) -> VecMap<DefId, OpaqueHiddenType<'tcx>> { |
| 59 | + let mut result: VecMap<DefId, OpaqueHiddenType<'tcx>> = VecMap::new(); |
59 | 60 | for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls { |
60 | 61 | let substs = opaque_type_key.substs; |
61 | 62 | debug!(?concrete_type, ?substs); |
@@ -124,21 +125,31 @@ impl<'tcx> RegionInferenceContext<'tcx> { |
124 | 125 | // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)` |
125 | 126 | // and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that |
126 | 127 | // once we convert the generic parameters to those of the opaque type. |
127 | | - if let Some(prev) = result.get_mut(&opaque_type_key) { |
| 128 | + if let Some(prev) = result.get_mut(&opaque_type_key.def_id) { |
128 | 129 | if prev.ty != ty { |
129 | | - let mut err = infcx.tcx.sess.struct_span_err( |
130 | | - concrete_type.span, |
131 | | - &format!("hidden type `{}` differed from previous `{}`", ty, prev.ty), |
132 | | - ); |
133 | | - err.span_note(prev.span, "previous hidden type bound here"); |
134 | | - err.emit(); |
| 130 | + if !ty.references_error() { |
| 131 | + let mut err = infcx.tcx.sess.struct_span_err( |
| 132 | + concrete_type.span, |
| 133 | + "concrete type differs from previous defining opaque type use", |
| 134 | + ); |
| 135 | + err.span_label(prev.span, format!("expected `{}`, got `{}`", prev.ty, ty)); |
| 136 | + if prev.span == concrete_type.span { |
| 137 | + err.span_label(prev.span, "this expression supplies two conflicting concrete types for the same opaque type"); |
| 138 | + } else { |
| 139 | + err.span_note(prev.span, "previous use here"); |
| 140 | + } |
| 141 | + err.emit(); |
| 142 | + } |
135 | 143 | prev.ty = infcx.tcx.ty_error(); |
136 | 144 | } |
137 | 145 | // Pick a better span if there is one. |
138 | 146 | // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. |
139 | 147 | prev.span = prev.span.substitute_dummy(concrete_type.span); |
140 | 148 | } else { |
141 | | - result.insert(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span }); |
| 149 | + result.insert( |
| 150 | + opaque_type_key.def_id, |
| 151 | + OpaqueHiddenType { ty, span: concrete_type.span }, |
| 152 | + ); |
142 | 153 | } |
143 | 154 | } |
144 | 155 | result |
|
0 commit comments