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,29 +269,41 @@ 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
- tcx. resolve_instance ( ( tcx. erase_regions ( & param_env) , def_id, tcx. erase_regions ( & substs) ) )
299
+
300
+ // HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)`
301
+ // below is more likely to ignore the bounds in scope (e.g. if the only
302
+ // generic parameters mentioned by `substs` were lifetime ones).
303
+ let substs = tcx. erase_regions ( & substs) ;
304
+
305
+ // FIXME(eddyb) should this always use `param_env.with_reveal_all()`?
306
+ tcx. resolve_instance ( tcx. erase_regions ( & param_env. and ( ( def_id, substs) ) ) )
294
307
}
295
308
296
309
pub fn resolve_for_fn_ptr (
@@ -300,7 +313,7 @@ impl<'tcx> Instance<'tcx> {
300
313
substs : SubstsRef < ' tcx > ,
301
314
) -> Option < Instance < ' tcx > > {
302
315
debug ! ( "resolve(def_id={:?}, substs={:?})" , def_id, substs) ;
303
- 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| {
304
317
match resolved. def {
305
318
InstanceDef :: Item ( def_id) if resolved. def . requires_caller_location ( tcx) => {
306
319
debug ! ( " => fn pointer created for function with #[track_caller]" ) ;
@@ -332,7 +345,7 @@ impl<'tcx> Instance<'tcx> {
332
345
debug ! ( " => associated item with unsizeable self: Self" ) ;
333
346
Some ( Instance { def : InstanceDef :: VtableShim ( def_id) , substs } )
334
347
} else {
335
- Instance :: resolve ( tcx, param_env, def_id, substs)
348
+ Instance :: resolve ( tcx, param_env, def_id, substs) . ok ( ) . flatten ( )
336
349
}
337
350
}
338
351
@@ -353,7 +366,7 @@ impl<'tcx> Instance<'tcx> {
353
366
pub fn resolve_drop_in_place ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> ty:: Instance < ' tcx > {
354
367
let def_id = tcx. require_lang_item ( DropInPlaceFnLangItem , None ) ;
355
368
let substs = tcx. intern_substs ( & [ ty. into ( ) ] ) ;
356
- Instance :: resolve ( tcx, ty:: ParamEnv :: reveal_all ( ) , def_id, substs) . unwrap ( )
369
+ Instance :: resolve ( tcx, ty:: ParamEnv :: reveal_all ( ) , def_id, substs) . unwrap ( ) . unwrap ( )
357
370
}
358
371
359
372
pub fn fn_once_adapter_instance (
0 commit comments