@@ -6,8 +6,14 @@ use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
6
6
use rustc_hir as hir;
7
7
use rustc_hir:: def:: { Namespace , Res } ;
8
8
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
9
- use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
10
- use rustc_infer:: { infer, traits} ;
9
+ use rustc_infer:: {
10
+ infer,
11
+ traits:: { self , Obligation } ,
12
+ } ;
13
+ use rustc_infer:: {
14
+ infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ,
15
+ traits:: ObligationCause ,
16
+ } ;
11
17
use rustc_middle:: ty:: adjustment:: {
12
18
Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability ,
13
19
} ;
@@ -17,6 +23,7 @@ use rustc_span::symbol::{sym, Ident};
17
23
use rustc_span:: Span ;
18
24
use rustc_target:: spec:: abi;
19
25
use rustc_trait_selection:: autoderef:: Autoderef ;
26
+ use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
20
27
use std:: iter;
21
28
22
29
/// Checks that it is legal to call methods of the trait corresponding
@@ -294,7 +301,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
294
301
expected : Expectation < ' tcx > ,
295
302
) -> Ty < ' tcx > {
296
303
let ( fn_sig, def_id) = match * callee_ty. kind ( ) {
297
- ty:: FnDef ( def_id, _) => ( callee_ty. fn_sig ( self . tcx ) , Some ( def_id) ) ,
304
+ ty:: FnDef ( def_id, subst) => {
305
+ // Unit testing: function items annotated with
306
+ // `#[rustc_evaluate_where_clauses]` trigger special output
307
+ // to let us test the trait evaluation system.
308
+ if self . tcx . has_attr ( def_id, sym:: rustc_evaluate_where_clauses) {
309
+ let predicates = self . tcx . predicates_of ( def_id) ;
310
+ let predicates = predicates. instantiate ( self . tcx , subst) ;
311
+ for ( predicate, predicate_span) in
312
+ predicates. predicates . iter ( ) . zip ( & predicates. spans )
313
+ {
314
+ let obligation = Obligation :: new (
315
+ ObligationCause :: dummy_with_span ( callee_expr. span ) ,
316
+ self . param_env ,
317
+ predicate. clone ( ) ,
318
+ ) ;
319
+ let result = self . infcx . evaluate_obligation ( & obligation) ;
320
+ self . tcx
321
+ . sess
322
+ . struct_span_err (
323
+ callee_expr. span ,
324
+ & format ! ( "evaluate({:?}) = {:?}" , predicate, result) ,
325
+ )
326
+ . span_label ( * predicate_span, "predicate" )
327
+ . emit ( ) ;
328
+ }
329
+ }
330
+ ( callee_ty. fn_sig ( self . tcx ) , Some ( def_id) )
331
+ }
298
332
ty:: FnPtr ( sig) => ( sig, None ) ,
299
333
ref t => {
300
334
let mut unit_variant = None ;
0 commit comments