Skip to content

Be more conservative about discarding caller_bound in ParamEnv::and #84472

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 2 commits into from
May 4, 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
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ impl FlagComputation {
&ty::Infer(infer) => {
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
match infer {
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {}
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {
self.add_flags(TypeFlags::HAS_TY_FRESH)
}

ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => {
self.add_flags(TypeFlags::HAS_TY_INFER)
Expand Down Expand Up @@ -278,7 +280,7 @@ impl FlagComputation {
ty::ConstKind::Infer(infer) => {
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
match infer {
InferConst::Fresh(_) => {}
InferConst::Fresh(_) => self.add_flags(TypeFlags::HAS_CT_FRESH),
InferConst::Var(_) => self.add_flags(TypeFlags::HAS_CT_INFER),
}
}
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_type_ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ bitflags! {
| TypeFlags::HAS_CT_INFER.bits
| TypeFlags::HAS_TY_PLACEHOLDER.bits
| TypeFlags::HAS_CT_PLACEHOLDER.bits
// We consider 'freshened' types and constants
// to depend on a particular fn.
// The freshening process throws away information,
// which can make things unsuitable for use in a global
// cache. Note that there is no 'fresh lifetime' flag -
// freshening replaces all lifetimes with `ReErased`,
// which is different from how types/const are freshened.
| TypeFlags::HAS_TY_FRESH.bits
| TypeFlags::HAS_CT_FRESH.bits
| TypeFlags::HAS_FREE_LOCAL_REGIONS.bits;

/// Does this have `Projection`?
Expand Down Expand Up @@ -90,6 +99,12 @@ bitflags! {
/// Does this value have parameters/placeholders/inference variables which could be
/// replaced later, in a way that would change the results of `impl` specialization?
const STILL_FURTHER_SPECIALIZABLE = 1 << 17;

/// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`?
const HAS_TY_FRESH = 1 << 18;

/// Does this value have `InferConst::Fresh`?
const HAS_CT_FRESH = 1 << 19;
}
}

Expand Down
55 changes: 55 additions & 0 deletions src/test/ui/traits/issue-84399-bad-fresh-caching.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// compile-flags: --crate-type lib
// check-pass
//
// Regression test for issue #84399
// Tests that we keep the full `ParamEnv` when
// caching predicates with freshened types in the global cache

use std::marker::PhantomData;
pub trait Allocator<R> {
type Buffer;
}
pub struct DefaultAllocator;
impl <R> Allocator<R> for DefaultAllocator {
type Buffer = ();
}
pub type Owned<R> = <DefaultAllocator as Allocator<R>>::Buffer;
pub type MatrixMN<R> = Matrix<R, Owned<R>>;
pub type Matrix4<N> = Matrix<N, ()>;
pub struct Matrix<R, S> {
pub data: S,
_phantoms: PhantomData<R>,
}
pub fn set_object_transform(matrix: &Matrix4<()>) {
matrix.js_buffer_view();
}
pub trait Storable {
type Cell;
fn slice_to_items(_buffer: &()) -> &[Self::Cell] {
unimplemented!()
}
}
pub type Cell<T> = <T as Storable>::Cell;
impl<R> Storable for MatrixMN<R>
where
DefaultAllocator: Allocator<R>,
{
type Cell = ();
}
pub trait JsBufferView {
fn js_buffer_view(&self) -> usize {
unimplemented!()
}
}
impl<R> JsBufferView for [MatrixMN<R>]
where
DefaultAllocator: Allocator<R>,
MatrixMN<R>: Storable,
[Cell<MatrixMN<R>>]: JsBufferView,
{
fn js_buffer_view(&self) -> usize {
<MatrixMN<R> as Storable>::slice_to_items(&()).js_buffer_view()
}
}
impl JsBufferView for [()] {}
impl<R> JsBufferView for MatrixMN<R> where DefaultAllocator: Allocator<R> {}