Avoid having to handle an Option
in the type system
This commit is contained in:
parent
4f2b108816
commit
0e7b283573
21 changed files with 146 additions and 109 deletions
|
@ -21,8 +21,9 @@ pub mod generics;
|
||||||
mod lint;
|
mod lint;
|
||||||
|
|
||||||
use std::assert_matches::assert_matches;
|
use std::assert_matches::assert_matches;
|
||||||
use std::slice;
|
use std::{char, slice};
|
||||||
|
|
||||||
|
use rustc_abi::Size;
|
||||||
use rustc_ast::TraitObjectSyntax;
|
use rustc_ast::TraitObjectSyntax;
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
|
@ -31,7 +32,7 @@ use rustc_errors::{
|
||||||
};
|
};
|
||||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
|
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
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::infer::{InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_middle::middle::stability::AllowUnstable;
|
use rustc_middle::middle::stability::AllowUnstable;
|
||||||
|
@ -2693,20 +2694,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let ty = self.lower_ty(ty);
|
let ty = self.lower_ty(ty);
|
||||||
let pat_ty = match pat.kind {
|
let pat_ty = match pat.kind {
|
||||||
hir::TyPatKind::Range(start, end, include_end) => {
|
hir::TyPatKind::Range(start, end, include_end) => {
|
||||||
let ty = match ty.kind() {
|
let (ty, start, end) = match ty.kind() {
|
||||||
ty::Int(_) | ty::Uint(_) | ty::Char => ty,
|
ty::Int(_) | ty::Uint(_) | ty::Char => {
|
||||||
_ => Ty::new_error(
|
let (start, end) = self.lower_ty_pat_range(ty, start, end);
|
||||||
tcx,
|
(ty, start, end)
|
||||||
self.dcx().emit_err(InvalidBaseType {
|
}
|
||||||
|
_ => {
|
||||||
|
let guar = self.dcx().emit_err(InvalidBaseType {
|
||||||
ty,
|
ty,
|
||||||
pat: "range",
|
pat: "range",
|
||||||
ty_span,
|
ty_span,
|
||||||
pat_span: pat.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 });
|
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
|
||||||
Ty::new_pat(tcx, ty, pat)
|
Ty::new_pat(tcx, ty, pat)
|
||||||
|
@ -2723,6 +2726,70 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
result_ty
|
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.
|
/// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR.
|
||||||
#[instrument(level = "debug", skip(self), ret)]
|
#[instrument(level = "debug", skip(self), ret)]
|
||||||
fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {
|
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) => {
|
ty::Pat(typ, pat) => {
|
||||||
match *pat {
|
match *pat {
|
||||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||||
if let Some(start) = start {
|
self.add_constraints_from_const(current, start, variance);
|
||||||
self.add_constraints_from_const(current, start, variance);
|
self.add_constraints_from_const(current, end, variance);
|
||||||
}
|
|
||||||
if let Some(end) = end {
|
|
||||||
self.add_constraints_from_const(current, end, variance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.add_constraints_from_ty(current, typ, variance);
|
self.add_constraints_from_ty(current, typ, variance);
|
||||||
|
|
|
@ -883,22 +883,14 @@ fn ty_is_known_nonnull<'tcx>(
|
||||||
try {
|
try {
|
||||||
match **pat {
|
match **pat {
|
||||||
ty::PatternKind::Range { start, end, include_end } => {
|
ty::PatternKind::Range { start, end, include_end } => {
|
||||||
match (start, end) {
|
let start = start.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||||
(Some(start), None) => {
|
let end = end.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||||
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)?;
|
|
||||||
|
|
||||||
match include_end {
|
match include_end {
|
||||||
RangeEnd::Included => start > 0 && end >= start,
|
// This also works for negative numbers, as we just need
|
||||||
RangeEnd::Excluded => start > 0 && end > start,
|
// to ensure we aren't wrapping over zero.
|
||||||
}
|
RangeEnd::Included => start > 0 && end >= start,
|
||||||
}
|
RangeEnd::Excluded => start > 0 && end > start,
|
||||||
_ => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,12 +221,8 @@ impl FlagComputation {
|
||||||
self.add_ty(ty);
|
self.add_ty(ty);
|
||||||
match *pat {
|
match *pat {
|
||||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||||
if let Some(start) = start {
|
self.add_const(start);
|
||||||
self.add_const(start)
|
self.add_const(end);
|
||||||
}
|
|
||||||
if let Some(end) = end {
|
|
||||||
self.add_const(end)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,14 +28,7 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
PatternKind::Range { start, end, include_end } => {
|
PatternKind::Range { start, end, include_end } => {
|
||||||
if let Some(start) = start {
|
write!(f, "{start}{include_end}{end}")
|
||||||
write!(f, "{start}")?;
|
|
||||||
}
|
|
||||||
write!(f, "{include_end}")?;
|
|
||||||
if let Some(end) = end {
|
|
||||||
write!(f, "{end}")?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,5 +37,5 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> {
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
|
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
|
||||||
pub enum PatternKind<'tcx> {
|
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_a, end: end_a, include_end: inc_a },
|
||||||
&ty::PatternKind::Range { start: start_b, end: end_b, include_end: inc_b },
|
&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 start = relation.relate(start_a, start_b)?;
|
||||||
let mut relate_opt_const = |a, b| match (a, b) {
|
// FIXME(pattern_types): make equal patterns equal (`0..5` is the same as `0..=6`).
|
||||||
(None, None) => Ok(None),
|
let end = relation.relate(end_a, end_b)?;
|
||||||
(Some(a), Some(b)) => relation.relate(a, b).map(Some),
|
if inc_a == inc_b {
|
||||||
// FIXME(pattern_types): report a better error
|
Ok(relation.cx().mk_pat(ty::PatternKind::Range {
|
||||||
_ => Err(TypeError::Mismatch),
|
start,
|
||||||
};
|
end,
|
||||||
let start = relate_opt_const(start_a, start_b)?;
|
include_end: inc_a,
|
||||||
let end = relate_opt_const(end_a, end_b)?;
|
}))
|
||||||
if inc_a != inc_b {
|
} else {
|
||||||
todo!()
|
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) => {
|
ty::Pat(ty, pat) => {
|
||||||
match *pat {
|
match *pat {
|
||||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||||
stack.extend(end.map(Into::into));
|
stack.push(end.into());
|
||||||
stack.extend(start.map(Into::into));
|
stack.push(start.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack.push(ty.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> {
|
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||||
tcx.mk_pat(match self {
|
tcx.mk_pat(match self {
|
||||||
Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range {
|
Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range {
|
||||||
start: start.as_ref().map(|c| c.internal(tables, tcx)),
|
start: start.as_ref().unwrap().internal(tables, tcx),
|
||||||
end: end.as_ref().map(|c| c.internal(tables, tcx)),
|
end: end.as_ref().unwrap().internal(tables, tcx),
|
||||||
include_end: if *include_end { RangeEnd::Included } else { RangeEnd::Excluded },
|
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 {
|
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||||
match **self {
|
match **self {
|
||||||
ty::PatternKind::Range { start, end, include_end } => stable_mir::ty::Pattern::Range {
|
ty::PatternKind::Range { start, end, include_end } => stable_mir::ty::Pattern::Range {
|
||||||
start: start.stable(tables),
|
// FIXME(SMIR): update data structures to not have an Option here anymore
|
||||||
end: end.stable(tables),
|
start: Some(start.stable(tables)),
|
||||||
|
end: Some(end.stable(tables)),
|
||||||
include_end: matches!(include_end, rustc_hir::RangeEnd::Included),
|
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::Pat(ty, pat) => match *pat {
|
||||||
ty::PatternKind::Range { start, end, include_end } => {
|
ty::PatternKind::Range { start, end, include_end } => {
|
||||||
let consts = [
|
let consts = [
|
||||||
start.unwrap_or(self.tcx.consts.unit),
|
start,
|
||||||
end.unwrap_or(self.tcx.consts.unit),
|
end,
|
||||||
ty::Const::from_bool(
|
ty::Const::from_bool(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
matches!(include_end, rustc_hir::RangeEnd::Included),
|
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);
|
||||||
check(start)
|
check(end);
|
||||||
}
|
|
||||||
if let Some(end) = end {
|
|
||||||
check(end)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,21 +209,18 @@ fn layout_of_uncached<'tcx>(
|
||||||
if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
|
if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
|
||||||
&mut layout.backend_repr
|
&mut layout.backend_repr
|
||||||
{
|
{
|
||||||
if let Some(start) = start {
|
scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
|
||||||
scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
|
.try_to_bits(tcx, cx.typing_env)
|
||||||
.try_to_bits(tcx, cx.typing_env)
|
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
|
||||||
}
|
let mut end = extract_const_value(cx, ty, end)?
|
||||||
if let Some(end) = end {
|
.try_to_bits(tcx, cx.typing_env)
|
||||||
let mut end = extract_const_value(cx, ty, end)?
|
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||||
.try_to_bits(tcx, cx.typing_env)
|
match include_end {
|
||||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
rustc_hir::RangeEnd::Included => {}
|
||||||
match include_end {
|
rustc_hir::RangeEnd::Excluded => end = end.wrapping_sub(1),
|
||||||
rustc_hir::RangeEnd::Included => {}
|
|
||||||
rustc_hir::RangeEnd::Excluded => end = end.wrapping_sub(1),
|
|
||||||
}
|
|
||||||
scalar.valid_range_mut().end = end;
|
|
||||||
}
|
}
|
||||||
|
scalar.valid_range_mut().end = end;
|
||||||
|
|
||||||
let niche = Niche {
|
let niche = Niche {
|
||||||
offset: Size::ZERO,
|
offset: Size::ZERO,
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
fn main() -> () {
|
fn main() -> () {
|
||||||
let mut _0: ();
|
let mut _0: ();
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug x => const 2_u32 is 1..=;
|
debug x => const 2_u32 is 1..=u32::MAX;
|
||||||
scope 2 {
|
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
|
// EMIT_MIR pattern_types.main.PreCodegen.after.mir
|
||||||
fn main() {
|
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) };
|
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) };
|
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
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
= note: enum has no representation hint
|
= 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
|
--> $DIR/clashing-extern-fn.rs:502:54
|
||||||
|
|
|
|
||||||
LL | fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(usize is 0..)>;
|
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 ();
|
LL | fn pt_non_null_ptr() -> *const ();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 ()`
|
found `unsafe extern "C" fn() -> *const ()`
|
||||||
|
|
||||||
warning: 24 warnings emitted
|
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
|
--> $DIR/nested.rs:10:34
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
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!();
|
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
|
--> $DIR/nested.rs:15:35
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
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!();
|
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
|
--> $DIR/nested.rs:19:35
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
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
|
--> $DIR/nested.rs:10:63
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
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}`
|
found type `{integer}`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/nested.rs:15:67
|
--> $DIR/nested.rs:15:67
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
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}`
|
found type `{integer}`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/nested.rs:19:66
|
--> $DIR/nested.rs:19:66
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
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}`
|
found type `{integer}`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
|
|
|
@ -44,7 +44,7 @@ error: layout_of(NonZero<u32>) = Layout {
|
||||||
LL | type X = std::num::NonZeroU32;
|
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),
|
size: Size(4 bytes),
|
||||||
align: AbiAndPrefAlign {
|
align: AbiAndPrefAlign {
|
||||||
abi: Align(4 bytes),
|
abi: Align(4 bytes),
|
||||||
|
@ -83,7 +83,7 @@ error: layout_of((u32) is 1..=) = Layout {
|
||||||
LL | type Y = pattern_type!(u32 is 1..);
|
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),
|
size: Size(4 bytes),
|
||||||
align: AbiAndPrefAlign {
|
align: AbiAndPrefAlign {
|
||||||
abi: Align(4 bytes),
|
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 {}
|
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: 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
|
= 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) };
|
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)
|
= note: target type: `Option<u32>` (64 bits)
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -11,5 +11,5 @@ type Z = Option<pattern_type!(u32 is 1..)>;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x: Y = unsafe { std::mem::transmute(42_u32) };
|
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
|
--> $DIR/range_patterns_unusable_math.rs:14:15
|
||||||
|
|
|
|
||||||
LL | let x = x + 1_u32;
|
LL | let x = x + 1_u32;
|
||||||
| - ^ ----- u32
|
| - ^ ----- u32
|
||||||
| |
|
| |
|
||||||
| (u32) is 1..=
|
| (u32) is 1..=u32::MAX
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue