@@ -36,6 +36,9 @@ open Microsoft.FSharp.Core.CompilerServices
3636let ImportType scoref amap m importInst ilty =
3737 ilty|> rescopeILType scoref|> Import.ImportILType amap m importInst
3838
39+ let CanImportType scoref amap m ilty =
40+ ilty|> rescopeILType scoref|> Import.CanImportILType amap m
41+
3942//-------------------------------------------------------------------------
4043// Fold the hierarchy.
4144// REVIEW: this code generalizes the iteration used below for member lookup.
@@ -86,17 +89,21 @@ let GetSuperTypeOfType g amap m typ =
8689/// Make a type for System.Collections.Generic.IList<ty>
8790let mkSystemCollectionsGenericIListTy g ty = TType_ app( g.tcref_ System_ Collections_ Generic_ IList,[ ty])
8891
92+ [<RequireQualifiedAccess>]
93+ /// Indicates whether we can skip interface types that lie outside the reference set
94+ type SkipUnrefInterfaces = Yes| No
95+
8996
9097/// Collect the set of immediate declared interface types for an F# type, but do not
9198/// traverse the type hierarchy to collect further interfaces.
92- let rec GetImmediateInterfacesOfType g amap m typ =
99+ let rec GetImmediateInterfacesOfType skipUnref g amap m typ=
93100let itys =
94101if isAppTy g typthen
95102let tcref , tinst = destAppTy g typ
96103if tcref.IsMeasureableReprTyconthen
97104[ match tcref.TypeReprInfowith
98105| TMeasureableRepr reprTy->
99- for ityin GetImmediateInterfacesOfType g amap m reprTydo
106+ for ityin GetImmediateInterfacesOfTypeskipUnref g amap m reprTydo
100107if isAppTy g itythen
101108let itcref = tcrefOfAppTy g ity
102109if not ( tyconRefEq g itcref g.system_ GenericIComparable_ tcref) &&
@@ -113,7 +120,18 @@ let rec GetImmediateInterfacesOfType g amap m typ =
113120yield Import.ImportProvidedType amap m ity]
114121#endif
115122| ILTypeMetadata( scoref, tdef) ->
116- tdef.Implements|> ILList.toList|> List.map( ImportType scoref amap m tinst)
123+
124+ // ImportType may fail for an interface if the assembly load set is incomplete and the interface
125+ // comes from another assembly. In this case we simply skip the interface:
126+ // if we don't skip it, then compilation will just fail here, and if type checking
127+ // succeeds with fewer non-dereferencable interfaces reported then it would have
128+ // succeeded with more reported. There are pathological corner cases where this
129+ // doesn't apply: e.g. for mscorlib interfaces like IComparable, but we can always
130+ // assume those are present.
131+ [ for ityin tdef.Implements|> ILList.toListdo
132+ if skipUnref= SkipUnrefInterfaces.No|| CanImportType scoref amap m itythen
133+ yield ImportType scoref amap m tinst ity]
134+
117135| FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata->
118136 tcref.ImmediateInterfaceTypesOfFSharpTycon|> List.map( instType( mkInstForAppTy g typ))
119137else
@@ -133,7 +151,7 @@ type AllowMultiIntfInstantiations = Yes | No
133151
134152/// Traverse the type hierarchy, e.g. f D (f C (f System.Object acc)).
135153/// Visit base types and interfaces first.
136- let private FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst visitor g amap m typ acc =
154+ let private FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInstskipUnref visitor g amap m typ acc =
137155let rec loop ndeep typ (( visitedTycon , visited : TyconRefMultiMap < _ >, acc ) as state ) =
138156
139157let seenThisTycon = isAppTy g typ&& Set.contains( tcrefOfAppTy g typ) .Stamp visitedTycon
@@ -157,7 +175,7 @@ let private FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst visitor g
157175if isInterfaceTy g typthen
158176 List.foldBack
159177( loop( ndeep+ 1 ))
160- ( GetImmediateInterfacesOfType g amap m typ)
178+ ( GetImmediateInterfacesOfTypeskipUnref g amap m typ)
161179( loop ndeep g.obj_ ty state)
162180elif isTyparTy g typthen
163181let tp = destTyparTy g typ
@@ -186,7 +204,7 @@ let private FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst visitor g
186204if followInterfacesthen
187205 List.foldBack
188206( loop( ndeep+ 1 ))
189- ( GetImmediateInterfacesOfType g amap m typ)
207+ ( GetImmediateInterfacesOfTypeskipUnref g amap m typ)
190208 state
191209else
192210 state
@@ -200,22 +218,25 @@ let private FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst visitor g
200218( visitedTycon, visited, acc)
201219 loop0 typ( Set.empty, TyconRefMultiMap<_>. Empty, acc) |> p33
202220
203- /// Fold, do not follow interfaces
204- let FoldPrimaryHierarchyOfType f g amap m allowMultiIntfInst typ acc = FoldHierarchyOfTypeAuxfalse allowMultiIntfInst f g amap m typ acc
221+ /// Fold, do not follow interfaces (unless the type is itself an interface)
222+ let FoldPrimaryHierarchyOfType f g amap m allowMultiIntfInst typ acc =
223+ FoldHierarchyOfTypeAuxfalse allowMultiIntfInst SkipUnrefInterfaces.No f g amap m typ acc
205224
206- /// Fold, following interfaces
207- let FoldEntireHierarchyOfType f g amap m allowMultiIntfInst typ acc = FoldHierarchyOfTypeAuxtrue allowMultiIntfInst f g amap m typ acc
225+ /// Fold, following interfaces. Skipping interfaces that lie outside the referenced assembly set is allowed.
226+ let FoldEntireHierarchyOfType f g amap m allowMultiIntfInst typ acc =
227+ FoldHierarchyOfTypeAuxtrue allowMultiIntfInst SkipUnrefInterfaces.Yes f g amap m typ acc
208228
209- /// Iterate, following interfaces
210- let IterateEntireHierarchyOfType f g amap m allowMultiIntfInst typ = FoldHierarchyOfTypeAuxtrue allowMultiIntfInst( fun ty () -> f ty) g amap m typ()
229+ /// Iterate, following interfaces. Skipping interfaces that lie outside the referenced assembly set is allowed.
230+ let IterateEntireHierarchyOfType f g amap m allowMultiIntfInst typ =
231+ FoldHierarchyOfTypeAuxtrue allowMultiIntfInst SkipUnrefInterfaces.Yes( fun ty () -> f ty) g amap m typ()
211232
212233/// Search for one element satisfying a predicate, following interfaces
213234let ExistsInEntireHierarchyOfType f g amap m allowMultiIntfInst typ =
214- FoldHierarchyOfTypeAuxtrue allowMultiIntfInst( fun ty acc -> acc|| f ty) g amap m typfalse
235+ FoldHierarchyOfTypeAuxtrue allowMultiIntfInstSkipUnrefInterfaces.Yes ( fun ty acc -> acc|| f ty) g amap m typfalse
215236
216237/// Search for one element where a function returns a 'Some' result, following interfaces
217238let SearchEntireHierarchyOfType f g amap m typ =
218- FoldHierarchyOfTypeAuxtrue AllowMultiIntfInstantiations.Yes
239+ FoldHierarchyOfTypeAuxtrue AllowMultiIntfInstantiations.Yes SkipUnrefInterfaces.Yes
219240( fun ty acc ->
220241match accwith
221242| None-> if f tythen Some( ty) else None
@@ -224,7 +245,7 @@ let SearchEntireHierarchyOfType f g amap m typ =
224245
225246/// Get all super types of the type, including the type itself
226247let AllSuperTypesOfType g amap m allowMultiIntfInst ty =
227- FoldHierarchyOfTypeAuxtrue allowMultiIntfInst( ListSet.insert( typeEquiv g)) g amap m ty[]
248+ FoldHierarchyOfTypeAuxtrue allowMultiIntfInstSkipUnrefInterfaces.No ( ListSet.insert( typeEquiv g)) g amap m ty[]
228249
229250/// Get all interfaces of a type, including the type itself if it is an interface
230251let AllInterfacesOfType g amap m allowMultiIntfInst ty =