From 05ac3ac575c2b11fbf493ac929ab60448a20e07e Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 8 Mar 2019 01:17:18 +0000 Subject: [PATCH] Define `super_combine_consts` Co-Authored-By: Gabriel Smith --- src/librustc/infer/combine.rs | 63 +++++++++++++++++++++++++++++++++-- 1 file 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( + &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,