@@ -13,6 +13,7 @@ use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisit
1313use rustc_middle:: ty:: subst:: { GenericArg , GenericArgKind , InternalSubsts , Subst , SubstsRef } ;
1414use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1515use rustc_span:: Span ;
16+ use smallvec:: { smallvec, SmallVec } ;
1617
1718use std:: ops:: ControlFlow ;
1819
@@ -37,7 +38,11 @@ pub struct OpaqueTypeDecl<'tcx> {
3738 /// fn foo<'a, 'b, T>() -> Foo<'a, T>
3839 ///
3940 /// then `substs` would be `['a, T]`.
40- pub substs : SubstsRef < ' tcx > ,
41+ ///
42+ /// In case there are multiple conflicting substs an error has already
43+ /// been reported, but we still store the additional substs here in order
44+ /// to allow for better diagnostics later.
45+ pub substs : SmallVec < [ SubstsRef < ' tcx > ; 1 ] > ,
4146
4247 /// The span of this particular definition of the opaque type. So
4348 /// for example:
@@ -429,11 +434,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
429434 // If there are required region bounds, we can use them.
430435 if opaque_defn. has_required_region_bounds {
431436 let bounds = tcx. explicit_item_bounds ( def_id) ;
432- debug ! ( "constrain_opaque_type: predicates: {:#?}" , bounds ) ;
437+ debug ! ( ?bounds , "predicates" ) ;
433438 let bounds: Vec < _ > =
434- bounds. iter ( ) . map ( |( bound, _) | bound. subst ( tcx, opaque_defn. substs ) ) . collect ( ) ;
435- debug ! ( "constrain_opaque_type: bounds={:#?}" , bounds) ;
436- let opaque_type = tcx. mk_opaque ( def_id, opaque_defn. substs ) ;
439+ bounds. iter ( ) . map ( |( bound, _) | bound. subst ( tcx, opaque_defn. substs [ 0 ] ) ) . collect ( ) ;
440+ debug ! ( ? bounds) ;
441+ let opaque_type = tcx. mk_opaque ( def_id, opaque_defn. substs [ 0 ] ) ;
437442
438443 let required_region_bounds =
439444 required_region_bounds ( tcx, opaque_type, bounds. into_iter ( ) ) ;
@@ -459,7 +464,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
459464 // second.
460465 let mut least_region = None ;
461466
462- for subst_arg in & opaque_defn. substs [ first_own_region..] {
467+ for subst_arg in & opaque_defn. substs [ 0 ] [ first_own_region..] {
463468 let subst_region = match subst_arg. unpack ( ) {
464469 GenericArgKind :: Lifetime ( r) => r,
465470 GenericArgKind :: Type ( _) | GenericArgKind :: Const ( _) => continue ,
@@ -532,7 +537,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
532537 // type can be equal to any of the region parameters of the
533538 // opaque type definition.
534539 let choice_regions: Lrc < Vec < ty:: Region < ' tcx > > > = Lrc :: new (
535- opaque_defn. substs [ first_own_region..]
540+ opaque_defn. substs [ 0 ] [ first_own_region..]
536541 . iter ( )
537542 . filter_map ( |arg| match arg. unpack ( ) {
538543 GenericArgKind :: Lifetime ( r) => Some ( r) ,
@@ -1095,18 +1100,40 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
10951100 let tcx = infcx. tcx ;
10961101
10971102 // Use the same type variable if the exact same opaque type appears more
1098- // than once in the return type (e.g., if it's passed to a type alias).
1099- if let Some ( opaque_defn) = self . opaque_types . get ( & def_id) {
1100- debug ! ( "instantiate_opaque_types: returning concrete ty {:?}" , opaque_defn. concrete_ty) ;
1101- return opaque_defn. concrete_ty ;
1103+ // than once in a function (e.g., if it's passed to a type alias).
1104+ if let Some ( opaque_defn) = self . opaque_types . get_mut ( & def_id) {
1105+ debug ! ( ?opaque_defn, "found already known concrete type" ) ;
1106+ if opaque_defn. substs . contains ( & substs) {
1107+ // Already seen this concrete type
1108+ return opaque_defn. concrete_ty ;
1109+ } else {
1110+ // Don't emit multiple errors for the same set of substs
1111+ opaque_defn. substs . push ( substs) ;
1112+ tcx. sess
1113+ . struct_span_err (
1114+ self . value_span ,
1115+ & format ! (
1116+ "defining use generics {:?} differ from previous defining use" ,
1117+ substs
1118+ ) ,
1119+ )
1120+ . span_note (
1121+ opaque_defn. definition_span ,
1122+ & format ! (
1123+ "previous defining use with different generics {:?} found here" ,
1124+ opaque_defn. substs[ 0 ]
1125+ ) ,
1126+ )
1127+ . delay_as_bug ( ) ;
1128+ }
11021129 }
11031130 let span = tcx. def_span ( def_id) ;
11041131 debug ! ( ?self . value_span, ?span) ;
11051132 let ty_var = infcx
11061133 . next_ty_var ( TypeVariableOrigin { kind : TypeVariableOriginKind :: TypeInference , span } ) ;
11071134
11081135 let item_bounds = tcx. explicit_item_bounds ( def_id) ;
1109- debug ! ( "instantiate_opaque_types: bounds={:#?}" , item_bounds) ;
1136+ debug ! ( ? item_bounds) ;
11101137 let bounds: Vec < _ > =
11111138 item_bounds. iter ( ) . map ( |( bound, _) | bound. subst ( tcx, substs) ) . collect ( ) ;
11121139
@@ -1115,16 +1142,16 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
11151142 infcx. partially_normalize_associated_types_in ( span, self . body_id , param_env, bounds) ;
11161143 self . obligations . extend ( obligations) ;
11171144
1118- debug ! ( "instantiate_opaque_types: bounds={:?}" , bounds) ;
1145+ debug ! ( ? bounds) ;
11191146
11201147 let required_region_bounds = required_region_bounds ( tcx, ty, bounds. iter ( ) . copied ( ) ) ;
1121- debug ! ( "instantiate_opaque_types: required_region_bounds={:?}" , required_region_bounds) ;
1148+ debug ! ( ? required_region_bounds) ;
11221149
11231150 // Make sure that we are in fact defining the *entire* type
11241151 // (e.g., `type Foo<T: Bound> = impl Bar;` needs to be
11251152 // defined by a function like `fn foo<T: Bound>() -> Foo<T>`).
1126- debug ! ( "instantiate_opaque_types: param_env={:#?}" , self . param_env, ) ;
1127- debug ! ( "instantiate_opaque_types: generics={:#?}" , tcx. generics_of( def_id) , ) ;
1153+ debug ! ( ? self . param_env, ) ;
1154+ debug ! ( generics= ? tcx. generics_of( def_id) , ) ;
11281155
11291156 // Ideally, we'd get the span where *this specific `ty` came
11301157 // from*, but right now we just use the span from the overall
@@ -1133,18 +1160,22 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
11331160 // Foo, impl Bar)`.
11341161 let definition_span = self . value_span ;
11351162
1136- self . opaque_types . insert (
1137- def_id,
1138- OpaqueTypeDecl {
1139- opaque_type : ty,
1140- substs,
1141- definition_span,
1142- concrete_ty : ty_var,
1143- has_required_region_bounds : !required_region_bounds. is_empty ( ) ,
1144- origin,
1145- } ,
1146- ) ;
1147- debug ! ( "instantiate_opaque_types: ty_var={:?}" , ty_var) ;
1163+ // We only keep the first concrete type var, as we will already error
1164+ // out if there are multiple due to the conflicting obligations
1165+ if !self . opaque_types . contains_key ( & def_id) {
1166+ self . opaque_types . insert (
1167+ def_id,
1168+ OpaqueTypeDecl {
1169+ opaque_type : ty,
1170+ substs : smallvec ! [ substs] ,
1171+ definition_span,
1172+ concrete_ty : ty_var,
1173+ has_required_region_bounds : !required_region_bounds. is_empty ( ) ,
1174+ origin,
1175+ } ,
1176+ ) ;
1177+ }
1178+ debug ! ( ?ty_var) ;
11481179
11491180 for predicate in & bounds {
11501181 if let ty:: PredicateKind :: Projection ( projection) = predicate. kind ( ) . skip_binder ( ) {
0 commit comments