@@ -23,7 +23,7 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
2323use rustc_middle:: infer:: unify_key:: { ConstVariableOrigin , ConstVariableOriginKind , ToType } ;
2424use rustc_middle:: mir:: interpret:: EvalToConstValueResult ;
2525use rustc_middle:: traits:: select;
26- use rustc_middle:: ty:: error:: { ExpectedFound , TypeError , UnconstrainedNumeric } ;
26+ use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
2727use rustc_middle:: ty:: fold:: { TypeFoldable , TypeFolder } ;
2828use rustc_middle:: ty:: relate:: RelateResult ;
2929use rustc_middle:: ty:: subst:: { GenericArg , GenericArgKind , InternalSubsts , SubstsRef } ;
@@ -46,7 +46,7 @@ use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, Veri
4646use self :: region_constraints:: {
4747 RegionConstraintCollector , RegionConstraintStorage , RegionSnapshot ,
4848} ;
49- use self :: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
49+ use self :: type_variable:: { Diverging , TypeVariableOrigin , TypeVariableOriginKind } ;
5050
5151pub mod at;
5252pub mod canonical;
@@ -679,10 +679,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
679679 t. fold_with ( & mut self . freshener ( ) )
680680 }
681681
682- pub fn type_var_diverges ( & ' a self , ty : Ty < ' _ > ) -> bool {
682+ /// Returns whether `ty` is a diverging type variable or not.
683+ /// (If `ty` is not a type variable at all, returns not diverging.)
684+ ///
685+ /// No attempt is made to resolve `ty`.
686+ pub fn type_var_diverges ( & ' a self , ty : Ty < ' _ > ) -> Diverging {
683687 match * ty. kind ( ) {
684688 ty:: Infer ( ty:: TyVar ( vid) ) => self . inner . borrow_mut ( ) . type_variables ( ) . var_diverges ( vid) ,
685- _ => false ,
689+ _ => Diverging :: NotDiverging ,
690+ }
691+ }
692+
693+ /// Returns the origin of the type variable identified by `vid`, or `None`
694+ /// if this is not a type variable.
695+ ///
696+ /// No attempt is made to resolve `ty`.
697+ pub fn type_var_origin ( & ' a self , ty : Ty < ' tcx > ) -> Option < TypeVariableOrigin > {
698+ match * ty. kind ( ) {
699+ ty:: Infer ( ty:: TyVar ( vid) ) => {
700+ Some ( * self . inner . borrow_mut ( ) . type_variables ( ) . var_origin ( vid) )
701+ }
702+ _ => None ,
686703 }
687704 }
688705
@@ -695,28 +712,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
695712 freshen:: TypeFreshener :: new ( self , true )
696713 }
697714
698- pub fn type_is_unconstrained_numeric ( & ' a self , ty : Ty < ' _ > ) -> UnconstrainedNumeric {
699- use rustc_middle:: ty:: error:: UnconstrainedNumeric :: Neither ;
700- use rustc_middle:: ty:: error:: UnconstrainedNumeric :: { UnconstrainedFloat , UnconstrainedInt } ;
701- match * ty. kind ( ) {
702- ty:: Infer ( ty:: IntVar ( vid) ) => {
703- if self . inner . borrow_mut ( ) . int_unification_table ( ) . probe_value ( vid) . is_some ( ) {
704- Neither
705- } else {
706- UnconstrainedInt
707- }
708- }
709- ty:: Infer ( ty:: FloatVar ( vid) ) => {
710- if self . inner . borrow_mut ( ) . float_unification_table ( ) . probe_value ( vid) . is_some ( ) {
711- Neither
712- } else {
713- UnconstrainedFloat
714- }
715- }
716- _ => Neither ,
717- }
718- }
719-
720715 pub fn unsolved_variables ( & self ) -> Vec < Ty < ' tcx > > {
721716 let mut inner = self . inner . borrow_mut ( ) ;
722717 let mut vars: Vec < Ty < ' _ > > = inner
@@ -969,29 +964,62 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
969964 ) ;
970965 }
971966
967+ /// Processes a `Coerce` predicate from the fulfillment context.
968+ /// This is NOT the preferred way to handle coercion, which is to
969+ /// invoke `FnCtxt::coerce` or a similar method (see `coercion.rs`).
970+ ///
971+ /// This method here is actually a fallback that winds up being
972+ /// invoked when `FnCtxt::coerce` encounters unresolved type variables
973+ /// and records a coercion predicate. Presently, this method is equivalent
974+ /// to `subtype_predicate` -- that is, "coercing" `a` to `b` winds up
975+ /// actually requiring `a <: b`. This is of course a valid coercion,
976+ /// but it's not as flexible as `FnCtxt::coerce` would be.
977+ ///
978+ /// (We may refactor this in the future, but there are a number of
979+ /// practical obstacles. Among other things, `FnCtxt::coerce` presently
980+ /// records adjustments that are required on the HIR in order to perform
981+ /// the coercion, and we don't currently have a way to manage that.)
982+ pub fn coerce_predicate (
983+ & self ,
984+ cause : & ObligationCause < ' tcx > ,
985+ param_env : ty:: ParamEnv < ' tcx > ,
986+ predicate : ty:: PolyCoercePredicate < ' tcx > ,
987+ ) -> Option < InferResult < ' tcx , ( ) > > {
988+ let subtype_predicate = predicate. map_bound ( |p| ty:: SubtypePredicate {
989+ a_is_expected : false , // when coercing from `a` to `b`, `b` is expected
990+ a : p. a ,
991+ b : p. b ,
992+ } ) ;
993+ self . subtype_predicate ( cause, param_env, subtype_predicate)
994+ }
995+
972996 pub fn subtype_predicate (
973997 & self ,
974998 cause : & ObligationCause < ' tcx > ,
975999 param_env : ty:: ParamEnv < ' tcx > ,
9761000 predicate : ty:: PolySubtypePredicate < ' tcx > ,
9771001 ) -> Option < InferResult < ' tcx , ( ) > > {
978- // Subtle: it's ok to skip the binder here and resolve because
979- // `shallow_resolve` just ignores anything that is not a type
980- // variable, and because type variable's can't (at present, at
1002+ // Check for two unresolved inference variables, in which case we can
1003+ // make no progress. This is partly a micro-optimization, but it's
1004+ // also an opportunity to "sub-unify" the variables. This isn't
1005+ // *necessary* to prevent cycles, because they would eventually be sub-unified
1006+ // anyhow during generalization, but it helps with diagnostics (we can detect
1007+ // earlier that they are sub-unified).
1008+ //
1009+ // Note that we can just skip the binders here because
1010+ // type variables can't (at present, at
9811011 // least) capture any of the things bound by this binder.
9821012 //
983- // NOTE(nmatsakis): really, there is no *particular* reason to do this
984- // `shallow_resolve` here except as a micro-optimization.
985- // Naturally I could not resist.
986- let two_unbound_type_vars = {
987- let a = self . shallow_resolve ( predicate. skip_binder ( ) . a ) ;
988- let b = self . shallow_resolve ( predicate. skip_binder ( ) . b ) ;
989- a. is_ty_var ( ) && b. is_ty_var ( )
990- } ;
991-
992- if two_unbound_type_vars {
993- // Two unbound type variables? Can't make progress.
994- return None ;
1013+ // Note that this sub here is not just for diagnostics - it has semantic
1014+ // effects as well.
1015+ let r_a = self . shallow_resolve ( predicate. skip_binder ( ) . a ) ;
1016+ let r_b = self . shallow_resolve ( predicate. skip_binder ( ) . b ) ;
1017+ match ( r_a. kind ( ) , r_b. kind ( ) ) {
1018+ ( & ty:: Infer ( ty:: TyVar ( a_vid) ) , & ty:: Infer ( ty:: TyVar ( b_vid) ) ) => {
1019+ self . inner . borrow_mut ( ) . type_variables ( ) . sub ( a_vid, b_vid) ;
1020+ return None ;
1021+ }
1022+ _ => { }
9951023 }
9961024
9971025 Some ( self . commit_if_ok ( |_snapshot| {
@@ -1020,25 +1048,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10201048 } )
10211049 }
10221050
1023- pub fn next_ty_var_id ( & self , diverging : bool , origin : TypeVariableOrigin ) -> TyVid {
1051+ pub fn next_ty_var_id ( & self , diverging : Diverging , origin : TypeVariableOrigin ) -> TyVid {
10241052 self . inner . borrow_mut ( ) . type_variables ( ) . new_var ( self . universe ( ) , diverging, origin)
10251053 }
10261054
10271055 pub fn next_ty_var ( & self , origin : TypeVariableOrigin ) -> Ty < ' tcx > {
1028- self . tcx . mk_ty_var ( self . next_ty_var_id ( false , origin) )
1056+ self . tcx . mk_ty_var ( self . next_ty_var_id ( Diverging :: NotDiverging , origin) )
10291057 }
10301058
10311059 pub fn next_ty_var_in_universe (
10321060 & self ,
10331061 origin : TypeVariableOrigin ,
10341062 universe : ty:: UniverseIndex ,
10351063 ) -> Ty < ' tcx > {
1036- let vid = self . inner . borrow_mut ( ) . type_variables ( ) . new_var ( universe, false , origin) ;
1064+ let vid = self . inner . borrow_mut ( ) . type_variables ( ) . new_var (
1065+ universe,
1066+ Diverging :: NotDiverging ,
1067+ origin,
1068+ ) ;
10371069 self . tcx . mk_ty_var ( vid)
10381070 }
10391071
10401072 pub fn next_diverging_ty_var ( & self , origin : TypeVariableOrigin ) -> Ty < ' tcx > {
1041- self . tcx . mk_ty_var ( self . next_ty_var_id ( true , origin) )
1073+ self . tcx . mk_ty_var ( self . next_ty_var_id ( Diverging :: Diverges , origin) )
10421074 }
10431075
10441076 pub fn next_const_var (
@@ -1152,7 +1184,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11521184 // as the substitutions for the default, `(T, U)`.
11531185 let ty_var_id = self . inner . borrow_mut ( ) . type_variables ( ) . new_var (
11541186 self . universe ( ) ,
1155- false ,
1187+ Diverging :: NotDiverging ,
11561188 TypeVariableOrigin {
11571189 kind : TypeVariableOriginKind :: TypeParameterDefinition (
11581190 param. name ,
0 commit comments