mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-14 21:16:50 +00:00
Avoid having to handle an Option
in the type system
This commit is contained in:
parent
4f2b108816
commit
0e7b283573
@ -21,8 +21,9 @@ pub mod generics;
|
||||
mod lint;
|
||||
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::slice;
|
||||
use std::{char, slice};
|
||||
|
||||
use rustc_abi::Size;
|
||||
use rustc_ast::TraitObjectSyntax;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_errors::codes::*;
|
||||
@ -31,7 +32,7 @@ use rustc_errors::{
|
||||
};
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
|
||||
use rustc_hir::{self as hir, AnonConst, ConstArg, GenericArg, GenericArgs, HirId};
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::middle::stability::AllowUnstable;
|
||||
@ -2693,20 +2694,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
let ty = self.lower_ty(ty);
|
||||
let pat_ty = match pat.kind {
|
||||
hir::TyPatKind::Range(start, end, include_end) => {
|
||||
let ty = match ty.kind() {
|
||||
ty::Int(_) | ty::Uint(_) | ty::Char => ty,
|
||||
_ => Ty::new_error(
|
||||
tcx,
|
||||
self.dcx().emit_err(InvalidBaseType {
|
||||
let (ty, start, end) = match ty.kind() {
|
||||
ty::Int(_) | ty::Uint(_) | ty::Char => {
|
||||
let (start, end) = self.lower_ty_pat_range(ty, start, end);
|
||||
(ty, start, end)
|
||||
}
|
||||
_ => {
|
||||
let guar = self.dcx().emit_err(InvalidBaseType {
|
||||
ty,
|
||||
pat: "range",
|
||||
ty_span,
|
||||
pat_span: pat.span,
|
||||
}),
|
||||
),
|
||||
});
|
||||
let errc = ty::Const::new_error(tcx, guar);
|
||||
(Ty::new_error(tcx, guar), errc, errc)
|
||||
}
|
||||
};
|
||||
let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
|
||||
let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
|
||||
|
||||
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
|
||||
Ty::new_pat(tcx, ty, pat)
|
||||
@ -2723,6 +2726,70 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
result_ty
|
||||
}
|
||||
|
||||
fn lower_ty_pat_range(
|
||||
&self,
|
||||
base: Ty<'tcx>,
|
||||
start: Option<&ConstArg<'tcx>>,
|
||||
end: Option<&ConstArg<'tcx>>,
|
||||
) -> (ty::Const<'tcx>, ty::Const<'tcx>) {
|
||||
let tcx = self.tcx();
|
||||
let size = match base.kind() {
|
||||
ty::Int(i) => {
|
||||
i.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits))
|
||||
}
|
||||
ty::Uint(ui) => {
|
||||
ui.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits))
|
||||
}
|
||||
ty::Char => Size::from_bytes(4),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let start =
|
||||
start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else(|| {
|
||||
match base.kind() {
|
||||
ty::Char | ty::Uint(_) => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(ty::ScalarInt::null(size)),
|
||||
base,
|
||||
),
|
||||
ty::Int(_) => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(
|
||||
ty::ScalarInt::truncate_from_int(size.signed_int_min(), size).0,
|
||||
),
|
||||
base,
|
||||
),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
});
|
||||
let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else(
|
||||
|| match base.kind() {
|
||||
ty::Char => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(
|
||||
ty::ScalarInt::truncate_from_uint(char::MAX, size).0,
|
||||
),
|
||||
base,
|
||||
),
|
||||
ty::Uint(_) => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(
|
||||
ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size).0,
|
||||
),
|
||||
base,
|
||||
),
|
||||
ty::Int(_) => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(
|
||||
ty::ScalarInt::truncate_from_int(size.signed_int_max(), size).0,
|
||||
),
|
||||
base,
|
||||
),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
);
|
||||
(start, end)
|
||||
}
|
||||
|
||||
/// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {
|
||||
|
@ -253,12 +253,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
ty::Pat(typ, pat) => {
|
||||
match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||
if let Some(start) = start {
|
||||
self.add_constraints_from_const(current, start, variance);
|
||||
}
|
||||
if let Some(end) = end {
|
||||
self.add_constraints_from_const(current, end, variance);
|
||||
}
|
||||
self.add_constraints_from_const(current, start, variance);
|
||||
self.add_constraints_from_const(current, end, variance);
|
||||
}
|
||||
}
|
||||
self.add_constraints_from_ty(current, typ, variance);
|
||||
|
@ -883,22 +883,14 @@ fn ty_is_known_nonnull<'tcx>(
|
||||
try {
|
||||
match **pat {
|
||||
ty::PatternKind::Range { start, end, include_end } => {
|
||||
match (start, end) {
|
||||
(Some(start), None) => {
|
||||
start.try_to_value()?.try_to_bits(tcx, typing_env)? > 0
|
||||
}
|
||||
(Some(start), Some(end)) => {
|
||||
let start =
|
||||
start.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||
let end =
|
||||
end.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||
let start = start.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||
let end = end.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||
|
||||
match include_end {
|
||||
RangeEnd::Included => start > 0 && end >= start,
|
||||
RangeEnd::Excluded => start > 0 && end > start,
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
match include_end {
|
||||
// This also works for negative numbers, as we just need
|
||||
// to ensure we aren't wrapping over zero.
|
||||
RangeEnd::Included => start > 0 && end >= start,
|
||||
RangeEnd::Excluded => start > 0 && end > start,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,12 +221,8 @@ impl FlagComputation {
|
||||
self.add_ty(ty);
|
||||
match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||
if let Some(start) = start {
|
||||
self.add_const(start)
|
||||
}
|
||||
if let Some(end) = end {
|
||||
self.add_const(end)
|
||||
}
|
||||
self.add_const(start);
|
||||
self.add_const(end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,14 +28,7 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
PatternKind::Range { start, end, include_end } => {
|
||||
if let Some(start) = start {
|
||||
write!(f, "{start}")?;
|
||||
}
|
||||
write!(f, "{include_end}")?;
|
||||
if let Some(end) = end {
|
||||
write!(f, "{end}")?;
|
||||
}
|
||||
Ok(())
|
||||
write!(f, "{start}{include_end}{end}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -44,5 +37,5 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> {
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
|
||||
pub enum PatternKind<'tcx> {
|
||||
Range { start: Option<ty::Const<'tcx>>, end: Option<ty::Const<'tcx>>, include_end: RangeEnd },
|
||||
Range { start: ty::Const<'tcx>, end: ty::Const<'tcx>, include_end: RangeEnd },
|
||||
}
|
||||
|
@ -54,19 +54,18 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for ty::Pattern<'tcx> {
|
||||
&ty::PatternKind::Range { start: start_a, end: end_a, include_end: inc_a },
|
||||
&ty::PatternKind::Range { start: start_b, end: end_b, include_end: inc_b },
|
||||
) => {
|
||||
// FIXME(pattern_types): make equal patterns equal (`0..=` is the same as `..=`).
|
||||
let mut relate_opt_const = |a, b| match (a, b) {
|
||||
(None, None) => Ok(None),
|
||||
(Some(a), Some(b)) => relation.relate(a, b).map(Some),
|
||||
// FIXME(pattern_types): report a better error
|
||||
_ => Err(TypeError::Mismatch),
|
||||
};
|
||||
let start = relate_opt_const(start_a, start_b)?;
|
||||
let end = relate_opt_const(end_a, end_b)?;
|
||||
if inc_a != inc_b {
|
||||
todo!()
|
||||
let start = relation.relate(start_a, start_b)?;
|
||||
// FIXME(pattern_types): make equal patterns equal (`0..5` is the same as `0..=6`).
|
||||
let end = relation.relate(end_a, end_b)?;
|
||||
if inc_a == inc_b {
|
||||
Ok(relation.cx().mk_pat(ty::PatternKind::Range {
|
||||
start,
|
||||
end,
|
||||
include_end: inc_a,
|
||||
}))
|
||||
} else {
|
||||
Err(TypeError::Mismatch)
|
||||
}
|
||||
Ok(relation.cx().mk_pat(ty::PatternKind::Range { start, end, include_end: inc_a }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,8 +138,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
||||
ty::Pat(ty, pat) => {
|
||||
match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||
stack.extend(end.map(Into::into));
|
||||
stack.extend(start.map(Into::into));
|
||||
stack.push(end.into());
|
||||
stack.push(start.into());
|
||||
}
|
||||
}
|
||||
stack.push(ty.into());
|
||||
|
@ -90,8 +90,8 @@ impl RustcInternal for Pattern {
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
tcx.mk_pat(match self {
|
||||
Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range {
|
||||
start: start.as_ref().map(|c| c.internal(tables, tcx)),
|
||||
end: end.as_ref().map(|c| c.internal(tables, tcx)),
|
||||
start: start.as_ref().unwrap().internal(tables, tcx),
|
||||
end: end.as_ref().unwrap().internal(tables, tcx),
|
||||
include_end: if *include_end { RangeEnd::Included } else { RangeEnd::Excluded },
|
||||
},
|
||||
})
|
||||
|
@ -406,8 +406,9 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
match **self {
|
||||
ty::PatternKind::Range { start, end, include_end } => stable_mir::ty::Pattern::Range {
|
||||
start: start.stable(tables),
|
||||
end: end.stable(tables),
|
||||
// FIXME(SMIR): update data structures to not have an Option here anymore
|
||||
start: Some(start.stable(tables)),
|
||||
end: Some(end.stable(tables)),
|
||||
include_end: matches!(include_end, rustc_hir::RangeEnd::Included),
|
||||
},
|
||||
}
|
||||
|
@ -415,8 +415,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||
ty::Pat(ty, pat) => match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end } => {
|
||||
let consts = [
|
||||
start.unwrap_or(self.tcx.consts.unit),
|
||||
end.unwrap_or(self.tcx.consts.unit),
|
||||
start,
|
||||
end,
|
||||
ty::Const::from_bool(
|
||||
self.tcx,
|
||||
matches!(include_end, rustc_hir::RangeEnd::Included),
|
||||
|
@ -738,12 +738,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(start) = start {
|
||||
check(start)
|
||||
}
|
||||
if let Some(end) = end {
|
||||
check(end)
|
||||
}
|
||||
check(start);
|
||||
check(end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,21 +209,18 @@ fn layout_of_uncached<'tcx>(
|
||||
if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
|
||||
&mut layout.backend_repr
|
||||
{
|
||||
if let Some(start) = start {
|
||||
scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
|
||||
.try_to_bits(tcx, cx.typing_env)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||
}
|
||||
if let Some(end) = end {
|
||||
let mut end = extract_const_value(cx, ty, end)?
|
||||
.try_to_bits(tcx, cx.typing_env)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||
match include_end {
|
||||
rustc_hir::RangeEnd::Included => {}
|
||||
rustc_hir::RangeEnd::Excluded => end = end.wrapping_sub(1),
|
||||
}
|
||||
scalar.valid_range_mut().end = end;
|
||||
scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
|
||||
.try_to_bits(tcx, cx.typing_env)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||
|
||||
let mut end = extract_const_value(cx, ty, end)?
|
||||
.try_to_bits(tcx, cx.typing_env)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||
match include_end {
|
||||
rustc_hir::RangeEnd::Included => {}
|
||||
rustc_hir::RangeEnd::Excluded => end = end.wrapping_sub(1),
|
||||
}
|
||||
scalar.valid_range_mut().end = end;
|
||||
|
||||
let niche = Niche {
|
||||
offset: Size::ZERO,
|
||||
|
@ -3,9 +3,9 @@
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
scope 1 {
|
||||
debug x => const 2_u32 is 1..=;
|
||||
debug x => const 2_u32 is 1..=u32::MAX;
|
||||
scope 2 {
|
||||
debug y => const {transmute(0x00000000): (u32) is 1..=};
|
||||
debug y => const {transmute(0x00000000): (u32) is 1..=u32::MAX};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@ use std::pat::pattern_type;
|
||||
|
||||
// EMIT_MIR pattern_types.main.PreCodegen.after.mir
|
||||
fn main() {
|
||||
// CHECK: debug x => const 2_u32 is 1..=
|
||||
// CHECK: debug x => const 2_u32 is 1..=u32::MAX
|
||||
let x: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(2) };
|
||||
// CHECK: debug y => const {transmute(0x00000000): (u32) is 1..=}
|
||||
// CHECK: debug y => const {transmute(0x00000000): (u32) is 1..=u32::MAX}
|
||||
let y: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) };
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
|
||||
warning: `extern` block uses type `Option<(usize) is 0..=>`, which is not FFI-safe
|
||||
warning: `extern` block uses type `Option<(usize) is 0..=usize::MAX>`, which is not FFI-safe
|
||||
--> $DIR/clashing-extern-fn.rs:502:54
|
||||
|
|
||||
LL | fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(usize is 0..)>;
|
||||
@ -276,7 +276,7 @@ LL | fn pt_non_null_ptr() -> pattern_type!(usize is 1..);
|
||||
LL | fn pt_non_null_ptr() -> *const ();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
||||
|
|
||||
= note: expected `unsafe extern "C" fn() -> (usize) is 1..=`
|
||||
= note: expected `unsafe extern "C" fn() -> (usize) is 1..=usize::MAX`
|
||||
found `unsafe extern "C" fn() -> *const ()`
|
||||
|
||||
warning: 24 warnings emitted
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: `(u32) is 1..=` is not a valid base type for range patterns
|
||||
error: `(u32) is 1..=u32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:10:34
|
||||
|
|
||||
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||
@ -10,7 +10,7 @@ note: range patterns only support integers
|
||||
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||
| ^^^
|
||||
|
||||
error: `(i32) is 1..=` is not a valid base type for range patterns
|
||||
error: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:15:35
|
||||
|
|
||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||
@ -22,7 +22,7 @@ note: range patterns only support integers
|
||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||
| ^^^^^
|
||||
|
||||
error: `(i32) is 1..=` is not a valid base type for range patterns
|
||||
error: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:19:35
|
||||
|
|
||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||
@ -62,27 +62,27 @@ error[E0308]: mismatched types
|
||||
--> $DIR/nested.rs:10:63
|
||||
|
|
||||
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||
| ^ expected `(u32) is 1..=`, found integer
|
||||
| ^ expected `(u32) is 1..=u32::MAX`, found integer
|
||||
|
|
||||
= note: expected pattern type `(u32) is 1..=`
|
||||
= note: expected pattern type `(u32) is 1..=u32::MAX`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/nested.rs:15:67
|
||||
|
|
||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||
| ^^ expected `(i32) is 1..=`, found integer
|
||||
| ^^ expected `(i32) is 1..=i32::MAX`, found integer
|
||||
|
|
||||
= note: expected pattern type `(i32) is 1..=`
|
||||
= note: expected pattern type `(i32) is 1..=i32::MAX`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/nested.rs:19:66
|
||||
|
|
||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||
| ^ expected `(i32) is 1..=`, found integer
|
||||
| ^ expected `(i32) is 1..=i32::MAX`, found integer
|
||||
|
|
||||
= note: expected pattern type `(i32) is 1..=`
|
||||
= note: expected pattern type `(i32) is 1..=i32::MAX`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
|
@ -44,7 +44,7 @@ error: layout_of(NonZero<u32>) = Layout {
|
||||
LL | type X = std::num::NonZeroU32;
|
||||
| ^^^^^^
|
||||
|
||||
error: layout_of((u32) is 1..=) = Layout {
|
||||
error: layout_of((u32) is 1..=u32::MAX) = Layout {
|
||||
size: Size(4 bytes),
|
||||
align: AbiAndPrefAlign {
|
||||
abi: Align(4 bytes),
|
||||
@ -83,7 +83,7 @@ error: layout_of((u32) is 1..=) = Layout {
|
||||
LL | type Y = pattern_type!(u32 is 1..);
|
||||
| ^^^^^^
|
||||
|
||||
error: layout_of(Option<(u32) is 1..=>) = Layout {
|
||||
error: layout_of(Option<(u32) is 1..=u32::MAX>) = Layout {
|
||||
size: Size(4 bytes),
|
||||
align: AbiAndPrefAlign {
|
||||
abi: Align(4 bytes),
|
||||
|
@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
||||
LL | impl Eq for Y {}
|
||||
| ^^^^^^^^^^^^-
|
||||
| |
|
||||
| `(u32) is 1..=` is not defined in the current crate
|
||||
| `(u32) is 1..=u32::MAX` is not defined in the current crate
|
||||
|
|
||||
= note: impl doesn't have any local type before any uncovered type parameters
|
||||
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
|
||||
|
@ -4,7 +4,7 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
|
||||
LL | let _: Option<u32> = unsafe { std::mem::transmute(z) };
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: source type: `Option<(u32) is 1..=>` (32 bits)
|
||||
= note: source type: `Option<(u32) is 1..=u32::MAX>` (32 bits)
|
||||
= note: target type: `Option<u32>` (64 bits)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -11,5 +11,5 @@ type Z = Option<pattern_type!(u32 is 1..)>;
|
||||
|
||||
fn main() {
|
||||
let x: Y = unsafe { std::mem::transmute(42_u32) };
|
||||
let x = x + 1_u32; //~ ERROR cannot add `u32` to `(u32) is 1..=`
|
||||
let x = x + 1_u32; //~ ERROR cannot add `u32` to `(u32) is 1..=u32::MAX`
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
error[E0369]: cannot add `u32` to `(u32) is 1..=`
|
||||
error[E0369]: cannot add `u32` to `(u32) is 1..=u32::MAX`
|
||||
--> $DIR/range_patterns_unusable_math.rs:14:15
|
||||
|
|
||||
LL | let x = x + 1_u32;
|
||||
| - ^ ----- u32
|
||||
| |
|
||||
| (u32) is 1..=
|
||||
| (u32) is 1..=u32::MAX
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user