Skip to content

canonicalize consts before calling try_unify_abstract_consts query #88166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 22, 2021
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
16 changes: 16 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,22 @@ pub struct CombinedSnapshot<'a, 'tcx> {
}

impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// calls `tcx.try_unify_abstract_consts` after
/// canonicalizing the consts.
pub fn try_unify_abstract_consts(
&self,
a: ty::Unevaluated<'tcx>,
b: ty::Unevaluated<'tcx>,
) -> bool {
let canonical = self.canonicalize_query(
((a.def, a.substs), (b.def, b.substs)),
&mut OriginalQueryValues::default(),
);
debug!("canonical consts: {:?}", &canonical.value);

self.tcx.try_unify_abstract_consts(canonical.value)
}

pub fn is_in_snapshot(&self) -> bool {
self.in_snapshot.get()
}
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,11 +552,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
(c1.val, c2.val)
{
if self
.selcx
.tcx()
.try_unify_abstract_consts(((a.def, a.substs), (b.def, b.substs)))
{
if infcx.try_unify_abstract_consts(a, b) {
return ProcessResult::Changed(vec![]);
}
}
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,10 +608,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
(c1.val, c2.val)
{
if self
.tcx()
.try_unify_abstract_consts(((a.def, a.substs), (b.def, b.substs)))
{
if self.infcx.try_unify_abstract_consts(a, b) {
return Ok(EvaluatedToOk);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// revisions: cfail
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features, unused_braces)]

trait Delegates<T> {}

struct FileCap<const Op: bool> {}

fn writes_to_path<C>(cap: &C)
where
C: Delegates<FileCap<{ false }>>,
{
writes_to_specific_path(&cap);
//~^ error: the trait bound
}

fn writes_to_specific_path<C>(cap: &C)
where
C: Delegates<FileCap<{ false }>>,
{
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// revisions: rpass
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features)]

struct Z;
const fn one() -> usize {
1
}

fn from_a_to_b<T>(source: [u8; one()]) -> T {
todo!()
}

fn not_main() {
let _: &Z = from_a_to_b([0; 1]);
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// revisions: rpass
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features)]

use std::{convert::TryFrom, num::NonZeroUsize};

struct A<const N: NonZeroUsize>([u8; N.get()])
where
[u8; N.get()]: Sized;

impl<'a, const N: NonZeroUsize> TryFrom<&'a [u8]> for A<N>
where
[u8; N.get()]: Sized,
{
type Error = ();
fn try_from(slice: &'a [u8]) -> Result<A<N>, ()> {
let _x = <&[u8; N.get()] as TryFrom<&[u8]>>::try_from(slice);
unimplemented!();
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// revisions: rpass
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features)]
pub trait IsTrue {}
pub trait IsFalse {}

pub struct Assert<const CHECK: bool> {}

impl IsTrue for Assert<true> {}
impl IsFalse for Assert<false> {}

pub struct SliceConstWriter<'a, const N: usize> {
ptr: &'a mut [u8],
}
impl<'a, const N: usize> SliceConstWriter<'a, { N }> {
pub fn from_slice(vec: &'a mut [u8]) -> Self {
Self { ptr: vec }
}

pub fn convert<const NN: usize>(mut self) -> SliceConstWriter<'a, { NN }> {
SliceConstWriter { ptr: self.ptr }
}
}

impl<'a, const N: usize> SliceConstWriter<'a, { N }>
where
Assert<{ N >= 2 }>: IsTrue,
{
pub fn write_u8(mut self) -> SliceConstWriter<'a, { N - 2 }> {
self.convert()
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// revisions: rpass
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features)]

pub struct Ref<'a, const NUM: usize>(&'a i32);

impl<'a, const NUM: usize> Ref<'a, NUM> {
pub fn foo<const A: usize>(r: Ref<'a, A>) -> Self
where
([(); NUM - A], [(); A - NUM]): Sized,
{
Self::bar(r)
}

pub fn bar<const A: usize>(r: Ref<'a, A>) -> Self
where
([(); NUM - A], [(); A - NUM]): Sized,
{
Self(r.0)
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// revisions: cfail
#![allow(incomplete_features)]
#![feature(const_generics, const_evaluatable_checked)]

pub struct Ref<'a>(&'a i32);

impl<'a> Ref<'a> {
pub fn foo<const A: usize>() -> [(); A - 0] {
Self::foo()
//~^ error: type annotations needed
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// revisions: rpass
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features)]

fn test<const SIZE: usize>() {}

trait SomeTrait {
const SIZE: usize;
}

struct A<'a, T> {
some_ref: &'a str,
_maker: core::marker::PhantomData<T>,
}

impl<'a, T: SomeTrait> A<'a, T>
where
[(); T::SIZE]: ,
{
fn call_test() {
test::<{ T::SIZE }>();
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// revisions: rpass
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features)]

struct Foo;
impl<'a> std::ops::Add<&'a Foo> for Foo
where
[(); 0 + 0]: Sized,
{
type Output = ();
fn add(self, _: &Foo) -> Self::Output {
loop {}
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// revisions: cfail
#![feature(const_generics, const_evaluatable_checked)]
#![allow(incomplete_features, unused_braces)]

struct Buffer<T, const S: usize>
where
[(); { S * 2 }]: Default,
{
data: [T; { S * 2 }],
}

struct BufferIter<'a, T, const S: usize>(&'a Buffer<T, S>)
where
[(); { S * 2 }]: Default;

impl<'a, T, const S: usize> Iterator for BufferIter<'a, T, S> {
//~^ error: the trait bound
//~^^ error: unconstrained generic constant
type Item = &'a T;

fn next(&mut self) -> Option<Self::Item> {
//~^ error: the trait bound
//~^^ error: unconstrained generic constant
None
}
}

fn main() {}