diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 4a9b68f24371d..966c5810171af 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -30,6 +30,7 @@ use super::sub::Sub; use super::type_variable::TypeVariableValue; use super::unify_key::{ConstVarValue, ConstVariableValue}; use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use super::unify_key::replace_if_possible; use crate::hir::def_id::DefId; use crate::mir::interpret::ConstValue; @@ -127,6 +128,12 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { where R: TypeRelation<'tcx>, { + debug!("{}.consts({:?}, {:?})", relation.tag(), a, b); + if a == b { return Ok(a); } + + let a = replace_if_possible(self.const_unification_table.borrow_mut(), a); + let b = replace_if_possible(self.const_unification_table.borrow_mut(), b); + let a_is_expected = relation.a_is_expected(); match (a.val, b.val) { diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index 96d40bc81add2..6065387647fa7 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -1,14 +1,12 @@ -use super::combine::{CombineFields, RelationDir, const_unification_error}; +use super::combine::{CombineFields, RelationDir}; use super::Subtype; use crate::hir::def_id::DefId; -use crate::ty::{self, Ty, TyCtxt, InferConst}; +use crate::ty::{self, Ty, TyCtxt}; use crate::ty::TyVar; use crate::ty::subst::SubstsRef; use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; -use crate::mir::interpret::ConstValue; -use crate::infer::unify_key::replace_if_possible; /// Ensures `a` is made equal to `b`. Returns `a` on success. pub struct Equate<'combine, 'infcx, 'tcx> { @@ -108,39 +106,7 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> { a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { - debug!("{}.consts({:?}, {:?})", self.tag(), a, b); - if a == b { return Ok(a); } - - let infcx = self.fields.infcx; - let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a); - let b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b); - let a_is_expected = self.a_is_expected(); - - match (a.val, b.val) { - (ConstValue::Infer(InferConst::Var(a_vid)), - ConstValue::Infer(InferConst::Var(b_vid))) => { - infcx.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); - } - - (ConstValue::Infer(InferConst::Var(a_id)), _) => { - self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?; - return Ok(a); - } - - (_, ConstValue::Infer(InferConst::Var(b_id))) => { - self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?; - return Ok(a); - } - - _ => {} - } - - self.fields.infcx.super_combine_consts(self, a, b)?; - Ok(a) + self.fields.infcx.super_combine_consts(self, a, b) } fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs index 10e45321a6d6a..37de54a7e8558 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -66,11 +66,6 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> { a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { - debug!("{}.consts({:?}, {:?})", self.tag(), a, b); - if a == b { - return Ok(a); - } - self.fields.infcx.super_combine_consts(self, a, b) } diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs index 8b64cda7bd26d..a1a94865e74e3 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -66,11 +66,6 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> { a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { - debug!("{}.consts({:?}, {:?})", self.tag(), a, b); - if a == b { - return Ok(a); - } - self.fields.infcx.super_combine_consts(self, a, b) } diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index 76db55ecfa8ef..67c97ef5d8b29 100644 --- a/src/librustc/infer/sub.rs +++ b/src/librustc/infer/sub.rs @@ -1,13 +1,11 @@ use super::SubregionOrigin; -use super::combine::{CombineFields, RelationDir, const_unification_error}; +use super::combine::{CombineFields, RelationDir}; use crate::traits::Obligation; -use crate::ty::{self, Ty, TyCtxt, InferConst}; +use crate::ty::{self, Ty, TyCtxt}; use crate::ty::TyVar; use crate::ty::fold::TypeFoldable; use crate::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; -use crate::infer::unify_key::replace_if_possible; -use crate::mir::interpret::ConstValue; use std::mem; /// Ensures `a` is made a subtype of `b`. Returns `a` on success. @@ -142,41 +140,7 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { - debug!("{}.consts({:?}, {:?})", self.tag(), a, b); - if a == b { return Ok(a); } - - let infcx = self.fields.infcx; - let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a); - let b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b); - - // Consts can only be equal or unequal to each other: there's no subtyping - // relation, so we're just going to perform equating here instead. - let a_is_expected = self.a_is_expected(); - match (a.val, b.val) { - (ConstValue::Infer(InferConst::Var(a_vid)), - ConstValue::Infer(InferConst::Var(b_vid))) => { - infcx.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); - } - - (ConstValue::Infer(InferConst::Var(a_id)), _) => { - self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?; - return Ok(a); - } - - (_, ConstValue::Infer(InferConst::Var(b_id))) => { - self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?; - return Ok(a); - } - - _ => {} - } - - self.fields.infcx.super_combine_consts(self, a, b)?; - Ok(a) + self.fields.infcx.super_combine_consts(self, a, b) } fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) diff --git a/src/test/ui/const-generics/issue-64519.rs b/src/test/ui/const-generics/issue-64519.rs new file mode 100644 index 0000000000000..72cce9b4843d7 --- /dev/null +++ b/src/test/ui/const-generics/issue-64519.rs @@ -0,0 +1,21 @@ +// check-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +struct Foo { + state: Option<[u8; D]>, +} + +impl Iterator for Foo<{D}> { + type Item = [u8; D]; + fn next(&mut self) -> Option { + if true { + return Some(self.state.unwrap().clone()); + } else { + return Some(self.state.unwrap().clone()); + } + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/issue-64519.stderr b/src/test/ui/const-generics/issue-64519.stderr new file mode 100644 index 0000000000000..d368f39d903a0 --- /dev/null +++ b/src/test/ui/const-generics/issue-64519.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/issue-64519.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default +