diff options
| author | varkor <github@varkor.com> | 2019-03-08 01:17:18 +0000 |
|---|---|---|
| committer | varkor <github@varkor.com> | 2019-05-01 23:10:57 +0100 |
| commit | 05ac3ac575c2b11fbf493ac929ab60448a20e07e (patch) | |
| tree | 7d93f0712f7b13f93c77a6b0f099ce7abe4056cd /src | |
| parent | d4e0951fff2161827e7fb83e346af37718759a2b (diff) | |
| download | rust-05ac3ac575c2b11fbf493ac929ab60448a20e07e.tar.gz rust-05ac3ac575c2b11fbf493ac929ab60448a20e07e.zip | |
Define `super_combine_consts`
Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/infer/combine.rs | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 885b439ef1c..16b0595b233 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -28,11 +28,13 @@ use super::{InferCtxt, MiscVariable, TypeTrace}; use super::lub::Lub; use super::sub::Sub; use super::type_variable::TypeVariableValue; +use super::const_variable::ConstVariableValue; use crate::hir::def_id::DefId; +use crate::mir::interpret::ConstValue; use crate::ty::{IntType, UintType}; -use crate::ty::{self, Ty, TyCtxt}; -use crate::ty::error::TypeError; +use crate::ty::{self, Ty, TyCtxt, InferConst, LazyConst}; +use crate::ty::error::{ConstError, TypeError}; use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; use crate::ty::subst::SubstsRef; use crate::traits::{Obligation, PredicateObligations}; @@ -107,13 +109,68 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> { Err(TypeError::Sorts(ty::relate::expected_found(relation, &a, &b))) } - _ => { ty::relate::super_relate_tys(relation, a, b) } } } + pub fn super_combine_consts<R>( + &self, + relation: &mut R, + a: &'tcx LazyConst<'tcx>, + b: &'tcx LazyConst<'tcx>, + ) -> RelateResult<'tcx, &'tcx LazyConst<'tcx>> + where + R: TypeRelation<'infcx, 'gcx, 'tcx>, + { + let a_is_expected = relation.a_is_expected(); + + if let (&ty::LazyConst::Evaluated(a_eval), &ty::LazyConst::Evaluated(b_eval)) = (a, b) { + match (a_eval.val, b_eval.val) { + (ConstValue::Infer(InferConst::Var(a_vid)), + ConstValue::Infer(InferConst::Var(b_vid))) => { + self.const_unification_table + .borrow_mut() + .unify_var_var(a_vid, b_vid) + .map_err(|e| const_unification_error(a_is_expected, e))?; + return Ok(a); + } + + // All other cases of inference with other variables are errors. + (ConstValue::Infer(InferConst::Var(_)), ConstValue::Infer(_)) | + (ConstValue::Infer(_), ConstValue::Infer(InferConst::Var(_))) => { + bug!("tried to combine ConstValue::Infer/ConstValue::Infer(InferConst::Var)") + } + + (ConstValue::Infer(InferConst::Var(vid)), _) => { + return self.unify_const_variable(a_is_expected, vid, b); + } + + (_, ConstValue::Infer(InferConst::Var(vid))) => { + return self.unify_const_variable(!a_is_expected, vid, a); + } + + _ => {} + } + } + + ty::relate::super_relate_consts(relation, a, b) + } + + pub fn unify_const_variable( + &self, + vid_is_expected: bool, + vid: ty::ConstVid<'tcx>, + value: &'tcx LazyConst<'tcx>, + ) -> RelateResult<'tcx, &'tcx LazyConst<'tcx>> { + self.const_unification_table + .borrow_mut() + .unify_var_value(vid, ConstVariableValue::Known { value }) + .map_err(|e| const_unification_error(vid_is_expected, e))?; + Ok(value) + } + fn unify_integral_variable(&self, vid_is_expected: bool, vid: ty::IntVid, |
