Rollup merge of #122820 - oli-obk:no_ord_def_id, r=estebank
Stop using `<DefId as Ord>` in various diagnostic situations work towards https://github.com/rust-lang/rust/issues/90317 Reverts part of https://github.com/rust-lang/rust/pull/106281, as it sorts constants and that's problematic since it can contain `ParamConst`, which contains `DefId`s
This commit is contained in:
commit
7481c0eab5
10 changed files with 197 additions and 161 deletions
|
@ -4236,6 +4236,7 @@ name = "rustc_middle"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.2",
|
"bitflags 2.4.2",
|
||||||
|
"derivative",
|
||||||
"either",
|
"either",
|
||||||
"field-offset",
|
"field-offset",
|
||||||
"gsgdt",
|
"gsgdt",
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
bitflags = "2.4.1"
|
bitflags = "2.4.1"
|
||||||
|
derivative = "2.2.0"
|
||||||
either = "1.5.0"
|
either = "1.5.0"
|
||||||
field-offset = "0.3.5"
|
field-offset = "0.3.5"
|
||||||
gsgdt = "0.1.2"
|
gsgdt = "0.1.2"
|
||||||
|
|
|
@ -456,7 +456,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An unevaluated (potentially generic) constant used in MIR.
|
/// An unevaluated (potentially generic) constant used in MIR.
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable)]
|
||||||
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable, Lift)]
|
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||||
pub struct UnevaluatedConst<'tcx> {
|
pub struct UnevaluatedConst<'tcx> {
|
||||||
pub def: DefId,
|
pub def: DefId,
|
||||||
|
|
|
@ -284,8 +284,15 @@ rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
|
||||||
/// order of the category, thereby influencing diagnostic output.
|
/// order of the category, thereby influencing diagnostic output.
|
||||||
///
|
///
|
||||||
/// See also `rustc_const_eval::borrow_check::constraints`.
|
/// See also `rustc_const_eval::borrow_check::constraints`.
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
|
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
|
||||||
|
#[derive(derivative::Derivative)]
|
||||||
|
#[derivative(
|
||||||
|
PartialOrd,
|
||||||
|
Ord,
|
||||||
|
PartialOrd = "feature_allow_slow_enum",
|
||||||
|
Ord = "feature_allow_slow_enum"
|
||||||
|
)]
|
||||||
pub enum ConstraintCategory<'tcx> {
|
pub enum ConstraintCategory<'tcx> {
|
||||||
Return(ReturnConstraint),
|
Return(ReturnConstraint),
|
||||||
Yield,
|
Yield,
|
||||||
|
@ -295,6 +302,7 @@ pub enum ConstraintCategory<'tcx> {
|
||||||
Cast {
|
Cast {
|
||||||
/// Whether this is an unsizing cast and if yes, this contains the target type.
|
/// Whether this is an unsizing cast and if yes, this contains the target type.
|
||||||
/// Region variables are erased to ReErased.
|
/// Region variables are erased to ReErased.
|
||||||
|
#[derivative(PartialOrd = "ignore", Ord = "ignore")]
|
||||||
unsize_to: Option<Ty<'tcx>>,
|
unsize_to: Option<Ty<'tcx>>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -304,7 +312,7 @@ pub enum ConstraintCategory<'tcx> {
|
||||||
ClosureBounds,
|
ClosureBounds,
|
||||||
|
|
||||||
/// Contains the function type if available.
|
/// Contains the function type if available.
|
||||||
CallArgument(Option<Ty<'tcx>>),
|
CallArgument(#[derivative(PartialOrd = "ignore", Ord = "ignore")] Option<Ty<'tcx>>),
|
||||||
CopyBound,
|
CopyBound,
|
||||||
SizedBound,
|
SizedBound,
|
||||||
Assignment,
|
Assignment,
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::error::UnsupportedFnAbi;
|
||||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use crate::query::TyCtxtAt;
|
use crate::query::TyCtxtAt;
|
||||||
use crate::ty::normalize_erasing_regions::NormalizationError;
|
use crate::ty::normalize_erasing_regions::NormalizationError;
|
||||||
use crate::ty::{self, ConstKind, Ty, TyCtxt, TypeVisitableExt};
|
use crate::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_error_messages::DiagMessage;
|
use rustc_error_messages::DiagMessage;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Diag, DiagArgValue, DiagCtxt, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
|
Diag, DiagArgValue, DiagCtxt, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
|
||||||
|
@ -356,21 +356,10 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
||||||
.ok_or_else(|| &*tcx.arena.alloc(LayoutError::SizeOverflow(ty)))?;
|
.ok_or_else(|| &*tcx.arena.alloc(LayoutError::SizeOverflow(ty)))?;
|
||||||
return Ok(SizeSkeleton::Known(Size::from_bytes(size)));
|
return Ok(SizeSkeleton::Known(Size::from_bytes(size)));
|
||||||
}
|
}
|
||||||
let len = tcx.expand_abstract_consts(len);
|
Err(tcx.arena.alloc(LayoutError::Unknown(ty)))
|
||||||
let prev = ty::Const::from_target_usize(tcx, s.bytes());
|
|
||||||
let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, prev) else {
|
|
||||||
return Err(tcx.arena.alloc(LayoutError::SizeOverflow(ty)));
|
|
||||||
};
|
|
||||||
Ok(SizeSkeleton::Generic(gen_size))
|
|
||||||
}
|
}
|
||||||
SizeSkeleton::Pointer { .. } => Err(err),
|
SizeSkeleton::Pointer { .. } => Err(err),
|
||||||
SizeSkeleton::Generic(g) => {
|
SizeSkeleton::Generic(_) => Err(tcx.arena.alloc(LayoutError::Unknown(ty))),
|
||||||
let len = tcx.expand_abstract_consts(len);
|
|
||||||
let Some(gen_size) = mul_sorted_consts(tcx, param_env, len, g) else {
|
|
||||||
return Err(tcx.arena.alloc(LayoutError::SizeOverflow(ty)));
|
|
||||||
};
|
|
||||||
Ok(SizeSkeleton::Generic(gen_size))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,56 +457,6 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When creating the layout for types with abstract consts in their size (i.e. [usize; 4 * N]),
|
|
||||||
/// to ensure that they have a canonical order and can be compared directly we combine all
|
|
||||||
/// constants, and sort the other terms. This allows comparison of expressions of sizes,
|
|
||||||
/// allowing for things like transmuting between types that depend on generic consts.
|
|
||||||
/// This returns `None` if multiplication of constants overflows.
|
|
||||||
fn mul_sorted_consts<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
a: ty::Const<'tcx>,
|
|
||||||
b: ty::Const<'tcx>,
|
|
||||||
) -> Option<ty::Const<'tcx>> {
|
|
||||||
use crate::mir::BinOp::Mul;
|
|
||||||
|
|
||||||
let mut work = vec![a, b];
|
|
||||||
let mut done = vec![];
|
|
||||||
while let Some(n) = work.pop() {
|
|
||||||
if let ConstKind::Expr(ty::Expr::Binop(Mul, l, r)) = n.kind() {
|
|
||||||
work.push(l);
|
|
||||||
work.push(r)
|
|
||||||
} else {
|
|
||||||
done.push(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut k = 1;
|
|
||||||
let mut overflow = false;
|
|
||||||
done.retain(|c| {
|
|
||||||
let Some(c) = c.try_eval_target_usize(tcx, param_env) else {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
let Some(next) = c.checked_mul(k) else {
|
|
||||||
overflow = true;
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
k = next;
|
|
||||||
false
|
|
||||||
});
|
|
||||||
if overflow {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
if k != 1 {
|
|
||||||
done.push(ty::Const::from_target_usize(tcx, k));
|
|
||||||
} else if k == 0 {
|
|
||||||
return Some(ty::Const::from_target_usize(tcx, 0));
|
|
||||||
}
|
|
||||||
done.sort_unstable();
|
|
||||||
|
|
||||||
// create a single tree from the buffer
|
|
||||||
done.into_iter().reduce(|acc, n| ty::Const::new_expr(tcx, ty::Expr::Binop(Mul, n, acc), n.ty()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait HasTyCtxt<'tcx>: HasDataLayout {
|
pub trait HasTyCtxt<'tcx>: HasDataLayout {
|
||||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,4 +32,79 @@ fn overflow(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 7777
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transpose<const W: usize, const H: usize>(v: [[u32;H]; W]) -> [[u32; W]; H] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ident<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [[u32; H]; W] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flatten<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [u32; W * H] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn coagulate<const W: usize, const H: usize>(v: [u32; H*W]) -> [[u32; W];H] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flatten_3d<const W: usize, const H: usize, const D: usize>(
|
||||||
|
v: [[[u32; D]; H]; W]
|
||||||
|
) -> [u32; D * W * H] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flatten_somewhat<const W: usize, const H: usize, const D: usize>(
|
||||||
|
v: [[[u32; D]; H]; W]
|
||||||
|
) -> [[u32; D * W]; H] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn known_size<const L: usize>(v: [u16; L]) -> [u8; L * 2] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn condense_bytes<const L: usize>(v: [u8; L * 2]) -> [u16; L] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn singleton_each<const L: usize>(v: [u8; L]) -> [[u8;1]; L] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpose_with_const<const W: usize, const H: usize>(
|
||||||
|
v: [[u32; 2 * H]; W + W]
|
||||||
|
) -> [[u32; W + W]; 2 * H] {
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(v)
|
||||||
|
//~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -4,8 +4,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: source type: `[[u32; H+1]; W]` (generic size (H + 1) * 4 * W)
|
= note: source type: `[[u32; H+1]; W]` (size can vary because of [u32; H+1])
|
||||||
= note: target type: `[[u32; W+1]; H]` (generic size (W + 1) * 4 * H)
|
= note: target type: `[[u32; W+1]; H]` (size can vary because of [u32; W+1])
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:16:5
|
--> $DIR/transmute-fail.rs:16:5
|
||||||
|
@ -22,8 +22,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: source type: `[[u32; H]; W]` (generic size 4 * H * W)
|
= note: source type: `[[u32; H]; W]` (size can vary because of [u32; H])
|
||||||
= note: target type: `[u32; W * H * H]` (generic size 4 * H * H * W)
|
= note: target type: `[u32; W * H * H]` (this type does not have a fixed size)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:30:5
|
--> $DIR/transmute-fail.rs:30:5
|
||||||
|
@ -34,6 +34,87 @@ LL | std::mem::transmute(v)
|
||||||
= note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[u32; 8888888]; 9999999]` are too big for the current architecture)
|
= note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[u32; 8888888]; 9999999]` are too big for the current architecture)
|
||||||
= note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type `[[u32; 9999999]; 777777777]` are too big for the current architecture)
|
= note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type `[[u32; 9999999]; 777777777]` are too big for the current architecture)
|
||||||
|
|
||||||
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
--> $DIR/transmute-fail.rs:37:5
|
||||||
|
|
|
||||||
|
LL | std::mem::transmute(v)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: source type: `[[u32; H]; W]` (size can vary because of [u32; H])
|
||||||
|
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
|
||||||
|
|
||||||
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
--> $DIR/transmute-fail.rs:50:5
|
||||||
|
|
|
||||||
|
LL | std::mem::transmute(v)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: source type: `[[u32; H]; W]` (size can vary because of [u32; H])
|
||||||
|
= note: target type: `[u32; W * H]` (this type does not have a fixed size)
|
||||||
|
|
||||||
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
--> $DIR/transmute-fail.rs:57:5
|
||||||
|
|
|
||||||
|
LL | std::mem::transmute(v)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: source type: `[u32; H*W]` (this type does not have a fixed size)
|
||||||
|
= note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
|
||||||
|
|
||||||
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
--> $DIR/transmute-fail.rs:66:5
|
||||||
|
|
|
||||||
|
LL | std::mem::transmute(v)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: source type: `[[[u32; D]; H]; W]` (size can vary because of [u32; D])
|
||||||
|
= note: target type: `[u32; D * W * H]` (this type does not have a fixed size)
|
||||||
|
|
||||||
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
--> $DIR/transmute-fail.rs:75:5
|
||||||
|
|
|
||||||
|
LL | std::mem::transmute(v)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: source type: `[[[u32; D]; H]; W]` (size can vary because of [u32; D])
|
||||||
|
= note: target type: `[[u32; D * W]; H]` (size can vary because of [u32; D * W])
|
||||||
|
|
||||||
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
--> $DIR/transmute-fail.rs:82:5
|
||||||
|
|
|
||||||
|
LL | std::mem::transmute(v)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: source type: `[u16; L]` (this type does not have a fixed size)
|
||||||
|
= note: target type: `[u8; L * 2]` (this type does not have a fixed size)
|
||||||
|
|
||||||
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
--> $DIR/transmute-fail.rs:89:5
|
||||||
|
|
|
||||||
|
LL | std::mem::transmute(v)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: source type: `[u8; L * 2]` (this type does not have a fixed size)
|
||||||
|
= note: target type: `[u16; L]` (this type does not have a fixed size)
|
||||||
|
|
||||||
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
--> $DIR/transmute-fail.rs:96:5
|
||||||
|
|
|
||||||
|
LL | std::mem::transmute(v)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: source type: `[u8; L]` (this type does not have a fixed size)
|
||||||
|
= note: target type: `[[u8; 1]; L]` (this type does not have a fixed size)
|
||||||
|
|
||||||
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
|
--> $DIR/transmute-fail.rs:105:5
|
||||||
|
|
|
||||||
|
LL | std::mem::transmute(v)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: source type: `[[u32; 2 * H]; W + W]` (size can vary because of [u32; 2 * H])
|
||||||
|
= note: target type: `[[u32; W + W]; 2 * H]` (size can vary because of [u32; W + W])
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/transmute-fail.rs:12:53
|
--> $DIR/transmute-fail.rs:12:53
|
||||||
|
|
|
|
||||||
|
@ -46,7 +127,7 @@ error[E0308]: mismatched types
|
||||||
LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
|
LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
|
||||||
| ^ expected `usize`, found `bool`
|
| ^ expected `usize`, found `bool`
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 15 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0512.
|
Some errors have detailed explanations: E0308, E0512.
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -3,81 +3,12 @@
|
||||||
#![feature(transmute_generic_consts)]
|
#![feature(transmute_generic_consts)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
fn transpose<const W: usize, const H: usize>(v: [[u32;H]; W]) -> [[u32; W]; H] {
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ident<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [[u32; H]; W] {
|
fn ident<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [[u32; H]; W] {
|
||||||
unsafe {
|
unsafe {
|
||||||
std::mem::transmute(v)
|
std::mem::transmute(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flatten<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [u32; W * H] {
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn coagulate<const W: usize, const H: usize>(v: [u32; H*W]) -> [[u32; W];H] {
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flatten_3d<const W: usize, const H: usize, const D: usize>(
|
|
||||||
v: [[[u32; D]; H]; W]
|
|
||||||
) -> [u32; D * W * H] {
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flatten_somewhat<const W: usize, const H: usize, const D: usize>(
|
|
||||||
v: [[[u32; D]; H]; W]
|
|
||||||
) -> [[u32; D * W]; H] {
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn known_size<const L: usize>(v: [u16; L]) -> [u8; L * 2] {
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn condense_bytes<const L: usize>(v: [u8; L * 2]) -> [u16; L] {
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn singleton_each<const L: usize>(v: [u8; L]) -> [[u8;1]; L] {
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transpose_with_const<const W: usize, const H: usize>(
|
|
||||||
v: [[u32; 2 * H]; W + W]
|
|
||||||
) -> [[u32; W + W]; 2 * H] {
|
|
||||||
unsafe {
|
|
||||||
std::mem::transmute(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = transpose([[0; 8]; 16]);
|
|
||||||
let _ = transpose_with_const::<8,4>([[0; 8]; 16]);
|
|
||||||
let _ = ident([[0; 8]; 16]);
|
let _ = ident([[0; 8]; 16]);
|
||||||
let _ = flatten([[0; 13]; 5]);
|
|
||||||
let _: [[_; 5]; 13] = coagulate([0; 65]);
|
|
||||||
let _ = flatten_3d([[[0; 3]; 13]; 5]);
|
|
||||||
let _ = flatten_somewhat([[[0; 3]; 13]; 5]);
|
|
||||||
let _ = known_size([16; 13]);
|
|
||||||
let _: [u16; 5] = condense_bytes([16u8; 10]);
|
|
||||||
let _ = singleton_each([16; 10]);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,17 +53,16 @@ LL | fn case2() {
|
||||||
error[E0597]: `a` does not live long enough
|
error[E0597]: `a` does not live long enough
|
||||||
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:30:26
|
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:30:26
|
||||||
|
|
|
|
||||||
LL | let a = 0;
|
LL | let a = 0;
|
||||||
| - binding `a` declared here
|
| - binding `a` declared here
|
||||||
LL | let cell = Cell::new(&a);
|
LL | let cell = Cell::new(&a);
|
||||||
| ^^ borrowed value does not live long enough
|
| ----------^^-
|
||||||
|
| | |
|
||||||
|
| | borrowed value does not live long enough
|
||||||
|
| argument requires that `a` is borrowed for `'static`
|
||||||
...
|
...
|
||||||
LL | / foo(cell, |cell_a, cell_x| {
|
LL | }
|
||||||
LL | | cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static -> borrow error
|
| - `a` dropped here while still borrowed
|
||||||
LL | | })
|
|
||||||
| |______- argument requires that `a` is borrowed for `'static`
|
|
||||||
LL | }
|
|
||||||
| - `a` dropped here while still borrowed
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
error[E0597]: `c` does not live long enough
|
error[E0597]: `c` does not live long enough
|
||||||
--> $DIR/adt-nullary-enums.rs:33:41
|
--> $DIR/adt-nullary-enums.rs:33:41
|
||||||
|
|
|
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | / combine(
|
LL | combine(
|
||||||
LL | | SomeEnum::SomeVariant(Cell::new(&c)),
|
LL | SomeEnum::SomeVariant(Cell::new(&c)),
|
||||||
| | ^^ borrowed value does not live long enough
|
| ----------^^-
|
||||||
LL | | SomeEnum::SomeOtherVariant::<Cell<&'static u32>>,
|
| | |
|
||||||
LL | | );
|
| | borrowed value does not live long enough
|
||||||
| |_____- argument requires that `c` is borrowed for `'static`
|
| argument requires that `c` is borrowed for `'static`
|
||||||
LL | }
|
...
|
||||||
| - `c` dropped here while still borrowed
|
LL | }
|
||||||
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
error[E0597]: `c` does not live long enough
|
error[E0597]: `c` does not live long enough
|
||||||
--> $DIR/adt-nullary-enums.rs:41:41
|
--> $DIR/adt-nullary-enums.rs:41:41
|
||||||
|
|
Loading…
Add table
Reference in a new issue