Auto merge of #3022 - RalfJung:upcast, r=compiler-errors
replace AsAny hack by trait upcasting :)
This commit is contained in:
commit
d4fbaa6fde
4 changed files with 22 additions and 31 deletions
|
@ -1,6 +1,5 @@
|
||||||
pub mod convert;
|
pub mod convert;
|
||||||
|
|
||||||
use std::any::Any;
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
@ -25,24 +24,6 @@ use rand::RngCore;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
/// A trait to work around not having trait object upcasting:
|
|
||||||
/// Add `AsAny` as supertrait and your trait objects can be turned into `&dyn Any` on which you can
|
|
||||||
/// then call `downcast`.
|
|
||||||
pub trait AsAny: Any {
|
|
||||||
fn as_any(&self) -> &dyn Any;
|
|
||||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
|
||||||
}
|
|
||||||
impl<T: Any> AsAny for T {
|
|
||||||
#[inline(always)]
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
#[inline(always)]
|
|
||||||
fn as_any_mut(&mut self) -> &mut dyn Any {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This mapping should match `decode_error_kind` in
|
// This mapping should match `decode_error_kind` in
|
||||||
// <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/unix/mod.rs>.
|
// <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/unix/mod.rs>.
|
||||||
const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = {
|
const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#![feature(round_ties_even)]
|
#![feature(round_ties_even)]
|
||||||
#![feature(os_str_bytes)]
|
#![feature(os_str_bytes)]
|
||||||
#![feature(lint_reasons)]
|
#![feature(lint_reasons)]
|
||||||
|
#![feature(trait_upcasting)]
|
||||||
// Configure clippy and other lints
|
// Configure clippy and other lints
|
||||||
#![allow(
|
#![allow(
|
||||||
clippy::collapsible_else_if,
|
clippy::collapsible_else_if,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::any::Any;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
@ -24,7 +25,7 @@ pub struct FileHandle {
|
||||||
writable: bool,
|
writable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FileDescriptor: std::fmt::Debug + helpers::AsAny {
|
pub trait FileDescriptor: std::fmt::Debug + Any {
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
||||||
fn read<'tcx>(
|
fn read<'tcx>(
|
||||||
|
@ -72,6 +73,18 @@ pub trait FileDescriptor: std::fmt::Debug + helpers::AsAny {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl dyn FileDescriptor {
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
|
||||||
|
(self as &dyn Any).downcast_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
|
||||||
|
(self as &mut dyn Any).downcast_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FileDescriptor for FileHandle {
|
impl FileDescriptor for FileHandle {
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
"FILE"
|
"FILE"
|
||||||
|
@ -689,7 +702,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
||||||
// FIXME: Support fullfsync for all FDs
|
// FIXME: Support fullfsync for all FDs
|
||||||
let FileHandle { file, writable } =
|
let FileHandle { file, writable } =
|
||||||
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
|
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
|
||||||
err_unsup_format!(
|
err_unsup_format!(
|
||||||
"`F_FULLFSYNC` is only supported on file-backed file descriptors"
|
"`F_FULLFSYNC` is only supported on file-backed file descriptors"
|
||||||
)
|
)
|
||||||
|
@ -1522,7 +1535,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
if let Some(file_descriptor) = this.machine.file_handler.handles.get_mut(&fd) {
|
if let Some(file_descriptor) = this.machine.file_handler.handles.get_mut(&fd) {
|
||||||
// FIXME: Support ftruncate64 for all FDs
|
// FIXME: Support ftruncate64 for all FDs
|
||||||
let FileHandle { file, writable } =
|
let FileHandle { file, writable } =
|
||||||
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
|
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
|
||||||
err_unsup_format!(
|
err_unsup_format!(
|
||||||
"`ftruncate64` is only supported on file-backed file descriptors"
|
"`ftruncate64` is only supported on file-backed file descriptors"
|
||||||
)
|
)
|
||||||
|
@ -1568,7 +1581,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
||||||
// FIXME: Support fsync for all FDs
|
// FIXME: Support fsync for all FDs
|
||||||
let FileHandle { file, writable } =
|
let FileHandle { file, writable } =
|
||||||
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
|
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
|
||||||
err_unsup_format!("`fsync` is only supported on file-backed file descriptors")
|
err_unsup_format!("`fsync` is only supported on file-backed file descriptors")
|
||||||
})?;
|
})?;
|
||||||
let io_result = maybe_sync_file(file, *writable, File::sync_all);
|
let io_result = maybe_sync_file(file, *writable, File::sync_all);
|
||||||
|
@ -1593,7 +1606,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
||||||
// FIXME: Support fdatasync for all FDs
|
// FIXME: Support fdatasync for all FDs
|
||||||
let FileHandle { file, writable } =
|
let FileHandle { file, writable } =
|
||||||
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
|
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
|
||||||
err_unsup_format!(
|
err_unsup_format!(
|
||||||
"`fdatasync` is only supported on file-backed file descriptors"
|
"`fdatasync` is only supported on file-backed file descriptors"
|
||||||
)
|
)
|
||||||
|
@ -1643,7 +1656,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
||||||
// FIXME: Support sync_data_range for all FDs
|
// FIXME: Support sync_data_range for all FDs
|
||||||
let FileHandle { file, writable } =
|
let FileHandle { file, writable } =
|
||||||
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
|
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
|
||||||
err_unsup_format!(
|
err_unsup_format!(
|
||||||
"`sync_data_range` is only supported on file-backed file descriptors"
|
"`sync_data_range` is only supported on file-backed file descriptors"
|
||||||
)
|
)
|
||||||
|
@ -1953,7 +1966,6 @@ impl FileMetadata {
|
||||||
let file = match option {
|
let file = match option {
|
||||||
Some(file_descriptor) =>
|
Some(file_descriptor) =>
|
||||||
&file_descriptor
|
&file_descriptor
|
||||||
.as_any()
|
|
||||||
.downcast_ref::<FileHandle>()
|
.downcast_ref::<FileHandle>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
err_unsup_format!(
|
err_unsup_format!(
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
use rustc_middle::ty::ScalarInt;
|
use rustc_middle::ty::ScalarInt;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
@ -7,8 +9,6 @@ use socketpair::SocketPair;
|
||||||
|
|
||||||
use shims::unix::fs::EvalContextExt as _;
|
use shims::unix::fs::EvalContextExt as _;
|
||||||
|
|
||||||
use std::cell::Cell;
|
|
||||||
|
|
||||||
pub mod epoll;
|
pub mod epoll;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod socketpair;
|
pub mod socketpair;
|
||||||
|
@ -81,7 +81,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
|
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
|
||||||
let epfd = epfd
|
let epfd = epfd
|
||||||
.as_any_mut()
|
|
||||||
.downcast_mut::<Epoll>()
|
.downcast_mut::<Epoll>()
|
||||||
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?;
|
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?;
|
||||||
|
|
||||||
|
@ -93,7 +92,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
} else if op == epoll_ctl_del {
|
} else if op == epoll_ctl_del {
|
||||||
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
|
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
|
||||||
let epfd = epfd
|
let epfd = epfd
|
||||||
.as_any_mut()
|
|
||||||
.downcast_mut::<Epoll>()
|
.downcast_mut::<Epoll>()
|
||||||
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?;
|
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?;
|
||||||
|
|
||||||
|
@ -154,7 +152,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
|
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
|
||||||
let _epfd = epfd
|
let _epfd = epfd
|
||||||
.as_any_mut()
|
|
||||||
.downcast_mut::<Epoll>()
|
.downcast_mut::<Epoll>()
|
||||||
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_wait`"))?;
|
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_wait`"))?;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue