Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/librustc/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
40 changes: 3 additions & 37 deletions src/librustc/infer/equate.rs
Original file line number Diff line number Diff line change
@@ -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> {
Expand Down Expand Up @@ -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<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
Expand Down
5 changes: 0 additions & 5 deletions src/librustc/infer/glb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
5 changes: 0 additions & 5 deletions src/librustc/infer/lub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
42 changes: 3 additions & 39 deletions src/librustc/infer/sub.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
Expand Down
21 changes: 21 additions & 0 deletions src/test/ui/const-generics/issue-64519.rs
Original file line number Diff line number Diff line change
@@ -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<const D: usize> {
state: Option<[u8; D]>,
}

impl<const D: usize> Iterator for Foo<{D}> {
type Item = [u8; D];
fn next(&mut self) -> Option<Self::Item> {
if true {
return Some(self.state.unwrap().clone());
} else {
return Some(self.state.unwrap().clone());
}
}
}

fn main() {}
8 changes: 8 additions & 0 deletions src/test/ui/const-generics/issue-64519.stderr
Original file line number Diff line number Diff line change
@@ -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