@@ -18,7 +18,7 @@ pub use self::ObligationCauseCode::*;
18
18
use middle:: subst;
19
19
use middle:: ty:: { self , HasProjectionTypes , Ty } ;
20
20
use middle:: ty_fold:: TypeFoldable ;
21
- use middle:: infer:: { self , InferCtxt } ;
21
+ use middle:: infer:: { self , fixup_err_to_string , InferCtxt } ;
22
22
use std:: slice:: Iter ;
23
23
use std:: rc:: Rc ;
24
24
use syntax:: ast;
@@ -395,53 +395,64 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
395
395
}
396
396
}
397
397
398
+ /// Normalizes the parameter environment, reporting errors if they occur.
398
399
pub fn normalize_param_env_or_error < ' a , ' tcx > ( unnormalized_env : ty:: ParameterEnvironment < ' a , ' tcx > ,
399
400
cause : ObligationCause < ' tcx > )
400
401
-> ty:: ParameterEnvironment < ' a , ' tcx >
401
402
{
402
- match normalize_param_env ( & unnormalized_env, cause) {
403
- Ok ( p) => p,
403
+ // I'm not wild about reporting errors here; I'd prefer to
404
+ // have the errors get reported at a defined place (e.g.,
405
+ // during typeck). Instead I have all parameter
406
+ // environments, in effect, going through this function
407
+ // and hence potentially reporting errors. This ensurse of
408
+ // course that we never forget to normalize (the
409
+ // alternative seemed like it would involve a lot of
410
+ // manual invocations of this fn -- and then we'd have to
411
+ // deal with the errors at each of those sites).
412
+ //
413
+ // In any case, in practice, typeck constructs all the
414
+ // parameter environments once for every fn as it goes,
415
+ // and errors will get reported then; so after typeck we
416
+ // can be sure that no errors should occur.
417
+
418
+ let tcx = unnormalized_env. tcx ;
419
+ let span = cause. span ;
420
+ let body_id = cause. body_id ;
421
+
422
+ debug ! ( "normalize_param_env_or_error(unnormalized_env={})" ,
423
+ unnormalized_env. repr( tcx) ) ;
424
+
425
+ let infcx = infer:: new_infer_ctxt ( tcx) ;
426
+ let predicates = match fully_normalize ( & infcx, & unnormalized_env, cause,
427
+ & unnormalized_env. caller_bounds ) {
428
+ Ok ( predicates) => predicates,
404
429
Err ( errors) => {
405
- // I'm not wild about reporting errors here; I'd prefer to
406
- // have the errors get reported at a defined place (e.g.,
407
- // during typeck). Instead I have all parameter
408
- // environments, in effect, going through this function
409
- // and hence potentially reporting errors. This ensurse of
410
- // course that we never forget to normalize (the
411
- // alternative seemed like it would involve a lot of
412
- // manual invocations of this fn -- and then we'd have to
413
- // deal with the errors at each of those sites).
414
- //
415
- // In any case, in practice, typeck constructs all the
416
- // parameter environments once for every fn as it goes,
417
- // and errors will get reported then; so after typeck we
418
- // can be sure that no errors should occur.
419
- let infcx = infer:: new_infer_ctxt ( unnormalized_env. tcx ) ;
420
430
report_fulfillment_errors ( & infcx, & errors) ;
421
-
422
- // Normalized failed? use what they gave us, it's better than nothing.
423
- unnormalized_env
431
+ return unnormalized_env; // an unnormalized env is better than nothing
424
432
}
425
- }
426
- }
427
-
428
- pub fn normalize_param_env < ' a , ' tcx > ( param_env : & ty:: ParameterEnvironment < ' a , ' tcx > ,
429
- cause : ObligationCause < ' tcx > )
430
- -> Result < ty:: ParameterEnvironment < ' a , ' tcx > ,
431
- Vec < FulfillmentError < ' tcx > > >
432
- {
433
- let tcx = param_env. tcx ;
434
-
435
- debug ! ( "normalize_param_env(param_env={})" ,
436
- param_env. repr( tcx) ) ;
433
+ } ;
437
434
438
- let infcx = infer:: new_infer_ctxt ( tcx) ;
439
- let predicates = try!( fully_normalize ( & infcx, param_env, cause, & param_env. caller_bounds ) ) ;
435
+ infcx. resolve_regions_and_report_errors ( body_id) ;
436
+ let predicates = match infcx. fully_resolve ( & predicates) {
437
+ Ok ( predicates) => predicates,
438
+ Err ( fixup_err) => {
439
+ // If we encounter a fixup error, it means that some type
440
+ // variable wound up unconstrained. I actually don't know
441
+ // if this can happen, and I certainly don't expect it to
442
+ // happen often, but if it did happen it probably
443
+ // represents a legitimate failure due to some kind of
444
+ // unconstrained variable, and it seems better not to ICE,
445
+ // all things considered.
446
+ let err_msg = fixup_err_to_string ( fixup_err) ;
447
+ tcx. sess . span_err ( span, & err_msg) ;
448
+ return unnormalized_env; // an unnormalized env is better than nothing
449
+ }
450
+ } ;
440
451
441
- debug ! ( "normalize_param_env : predicates={}" ,
452
+ debug ! ( "normalize_param_env_or_error : predicates={}" ,
442
453
predicates. repr( tcx) ) ;
443
454
444
- Ok ( param_env . with_caller_bounds ( predicates) )
455
+ unnormalized_env . with_caller_bounds ( predicates)
445
456
}
446
457
447
458
pub fn fully_normalize < ' a , ' tcx , T > ( infcx : & InferCtxt < ' a , ' tcx > ,
@@ -453,8 +464,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
453
464
{
454
465
let tcx = closure_typer. tcx ( ) ;
455
466
456
- debug ! ( "normalize_param_env(value={})" ,
457
- value. repr( tcx) ) ;
467
+ debug ! ( "normalize_param_env(value={})" , value. repr( tcx) ) ;
458
468
459
469
let mut selcx = & mut SelectionContext :: new ( infcx, closure_typer) ;
460
470
let mut fulfill_cx = FulfillmentContext :: new ( ) ;
@@ -468,8 +478,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
468
478
}
469
479
try!( fulfill_cx. select_all_or_error ( infcx, closure_typer) ) ;
470
480
let resolved_value = infcx. resolve_type_vars_if_possible ( & normalized_value) ;
471
- debug ! ( "normalize_param_env: resolved_value={}" ,
472
- resolved_value. repr( tcx) ) ;
481
+ debug ! ( "normalize_param_env: resolved_value={}" , resolved_value. repr( tcx) ) ;
473
482
Ok ( resolved_value)
474
483
}
475
484
0 commit comments