1
1
use crate :: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
2
2
use crate :: ty:: print:: { FmtPrinter , Printer } ;
3
3
use crate :: ty:: { self , SubstsRef , Ty , TyCtxt , TypeFoldable } ;
4
+ use rustc_errors:: ErrorReported ;
4
5
use rustc_hir:: def:: Namespace ;
5
6
use rustc_hir:: def_id:: { CrateNum , DefId } ;
6
7
use rustc_hir:: lang_items:: DropInPlaceFnLangItem ;
@@ -268,26 +269,31 @@ impl<'tcx> Instance<'tcx> {
268
269
/// this is used to find the precise code that will run for a trait method invocation,
269
270
/// if known.
270
271
///
271
- /// Returns `None` if we cannot resolve `Instance` to a specific instance.
272
+ /// Returns `Ok( None) ` if we cannot resolve `Instance` to a specific instance.
272
273
/// For example, in a context like this,
273
274
///
274
275
/// ```
275
276
/// fn foo<T: Debug>(t: T) { ... }
276
277
/// ```
277
278
///
278
- /// trying to resolve `Debug::fmt` applied to `T` will yield `None`, because we do not
279
+ /// trying to resolve `Debug::fmt` applied to `T` will yield `Ok( None) `, because we do not
279
280
/// know what code ought to run. (Note that this setting is also affected by the
280
281
/// `RevealMode` in the parameter environment.)
281
282
///
282
283
/// Presuming that coherence and type-check have succeeded, if this method is invoked
283
284
/// in a monomorphic context (i.e., like during codegen), then it is guaranteed to return
284
- /// `Some`.
285
+ /// `Ok(Some(instance))`.
286
+ ///
287
+ /// Returns `Err(ErrorReported)` when the `Instance` resolution process
288
+ /// couldn't complete due to errors elsewhere - this is distinct
289
+ /// from `Ok(None)` to avoid misleading diagnostics when an error
290
+ /// has already been/will be emitted, for the original cause
285
291
pub fn resolve (
286
292
tcx : TyCtxt < ' tcx > ,
287
293
param_env : ty:: ParamEnv < ' tcx > ,
288
294
def_id : DefId ,
289
295
substs : SubstsRef < ' tcx > ,
290
- ) -> Option < Instance < ' tcx > > {
296
+ ) -> Result < Option < Instance < ' tcx > > , ErrorReported > {
291
297
// All regions in the result of this query are erased, so it's
292
298
// fine to erase all of the input regions.
293
299
@@ -307,7 +313,7 @@ impl<'tcx> Instance<'tcx> {
307
313
substs : SubstsRef < ' tcx > ,
308
314
) -> Option < Instance < ' tcx > > {
309
315
debug ! ( "resolve(def_id={:?}, substs={:?})" , def_id, substs) ;
310
- Instance :: resolve ( tcx, param_env, def_id, substs) . map ( |mut resolved| {
316
+ Instance :: resolve ( tcx, param_env, def_id, substs) . ok ( ) . flatten ( ) . map ( |mut resolved| {
311
317
match resolved. def {
312
318
InstanceDef :: Item ( def_id) if resolved. def . requires_caller_location ( tcx) => {
313
319
debug ! ( " => fn pointer created for function with #[track_caller]" ) ;
@@ -339,7 +345,7 @@ impl<'tcx> Instance<'tcx> {
339
345
debug ! ( " => associated item with unsizeable self: Self" ) ;
340
346
Some ( Instance { def : InstanceDef :: VtableShim ( def_id) , substs } )
341
347
} else {
342
- Instance :: resolve ( tcx, param_env, def_id, substs)
348
+ Instance :: resolve ( tcx, param_env, def_id, substs) . ok ( ) . flatten ( )
343
349
}
344
350
}
345
351
@@ -360,7 +366,7 @@ impl<'tcx> Instance<'tcx> {
360
366
pub fn resolve_drop_in_place ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> ty:: Instance < ' tcx > {
361
367
let def_id = tcx. require_lang_item ( DropInPlaceFnLangItem , None ) ;
362
368
let substs = tcx. intern_substs ( & [ ty. into ( ) ] ) ;
363
- Instance :: resolve ( tcx, ty:: ParamEnv :: reveal_all ( ) , def_id, substs) . unwrap ( )
369
+ Instance :: resolve ( tcx, ty:: ParamEnv :: reveal_all ( ) , def_id, substs) . unwrap ( ) . unwrap ( )
364
370
}
365
371
366
372
pub fn fn_once_adapter_instance (
0 commit comments