Rust fix compilation for no_std targets #2 (#7553)

* Fix nightly no_std

* Fix nightly no_std
This commit is contained in:
Dan Lapid
2022-10-19 16:14:41 +03:00
committed by GitHub
parent 0edb275285
commit 5792623df4
11 changed files with 187 additions and 35 deletions

View File

@@ -12,14 +12,13 @@ categories = ["encoding", "data-structures", "memory-management"]
rust = "1.51"
[features]
default = ["thiserror"]
no_std = ["core2", "thiserror_core2"]
default = ["std"]
std = []
serialize = ["serde"]
[dependencies]
bitflags = "1.2.1"
serde = { version = "1.0", optional = true }
thiserror = { version = "1.0.30", optional = true }
core2 = { version = "0.4.0", optional = true }
# This version is compliant with mainline 1.0.30
thiserror_core2 = { version = "2.0.0", default-features = false, optional = true }
[build-dependencies]
rustc_version = "0.4.0"

12
rust/flatbuffers/build.rs Normal file
View File

@@ -0,0 +1,12 @@
use rustc_version::{version_meta, Channel};
fn main() {
let version_meta = version_meta().unwrap();
// To use nightly features we declare this and then we can use
// #[cfg(nightly)]
// for nightly only features
if version_meta.channel == Channel::Nightly {
println!("cargo:rustc-cfg=nightly")
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#[cfg(feature = "no_std")]
#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
use core::cmp::max;
use core::iter::{DoubleEndedIterator, ExactSizeIterator};

View File

@@ -28,9 +28,10 @@
//! At this time, to generate Rust code, you will need the latest `master` version of `flatc`, available from here: <https://github.com/google/flatbuffers>
//! (On OSX, you can install FlatBuffers from `HEAD` with the Homebrew package manager.)
#![cfg_attr(feature = "no_std", no_std)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(all(nightly, not(feature = "std")), feature(error_in_core))]
#[cfg(feature = "no_std")]
#[cfg(not(feature = "std"))]
extern crate alloc;
mod array;

View File

@@ -1,14 +1,14 @@
use crate::follow::Follow;
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
#[cfg(feature = "no_std")]
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::ops::Range;
use core::option::Option;
#[cfg(not(feature = "no_std"))]
use thiserror::Error;
#[cfg(feature = "no_std")]
use thiserror_core2::Error;
#[cfg(all(nightly, not(feature = "std")))]
use core::error::Error;
#[cfg(feature = "std")]
use std::error::Error;
/// Traces the location of data errors. Not populated for Dos detecting errors.
/// Useful for MissingRequiredField and Utf8Error in particular, though
@@ -41,64 +41,138 @@ impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
/// Describes how a flatuffer is invalid and, for data errors, roughly where. No extra tracing
/// information is given for DoS detecting errors since it will probably be a lot.
#[derive(Clone, Error, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum InvalidFlatbuffer {
#[error("Missing required field `{required}`.\n{error_trace}")]
MissingRequiredField {
required: &'static str,
error_trace: ErrorTrace,
},
#[error(
"Union exactly one of union discriminant (`{field_type}`) and value \
(`{field}`) are present.\n{error_trace}"
)]
InconsistentUnion {
field: &'static str,
field_type: &'static str,
error_trace: ErrorTrace,
},
#[error("Utf8 error for string in {range:?}: {error}\n{error_trace}")]
Utf8Error {
#[source]
error: core::str::Utf8Error,
range: Range<usize>,
error_trace: ErrorTrace,
},
#[error("String in range [{}, {}) is missing its null terminator.\n{error_trace}",
range.start, range.end)]
MissingNullTerminator {
range: Range<usize>,
error_trace: ErrorTrace,
},
#[error("Type `{unaligned_type}` at position {position} is unaligned.\n{error_trace}")]
Unaligned {
position: usize,
unaligned_type: &'static str,
error_trace: ErrorTrace,
},
#[error("Range [{}, {}) is out of bounds.\n{error_trace}", range.start, range.end)]
RangeOutOfBounds {
range: Range<usize>,
error_trace: ErrorTrace,
},
#[error(
"Signed offset at position {position} has value {soffset} which points out of bounds.\
\n{error_trace}"
)]
SignedOffsetOutOfBounds {
soffset: SOffsetT,
position: usize,
error_trace: ErrorTrace,
},
// Dos detecting errors. These do not get error traces since it will probably be very large.
#[error("Too many tables.")]
TooManyTables,
#[error("Apparent size too large.")]
ApparentSizeTooLarge,
#[error("Nested table depth limit reached.")]
DepthLimitReached,
}
#[cfg(any(nightly, feature = "std"))]
impl Error for InvalidFlatbuffer {
fn source(&self) -> Option<&(dyn Error + 'static)> {
if let InvalidFlatbuffer::Utf8Error { error: source, .. } = self {
Some(source)
} else {
None
}
}
}
impl core::fmt::Display for InvalidFlatbuffer {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
match self {
InvalidFlatbuffer::MissingRequiredField {
required,
error_trace,
} => {
writeln!(f, "Missing required field `{}`.\n{}", required, error_trace)?;
}
InvalidFlatbuffer::InconsistentUnion {
field,
field_type,
error_trace,
} => {
writeln!(
f,
"Exactly one of union discriminant (`{}`) and value (`{}`) are present.\n{}",
field_type, field, error_trace
)?;
}
InvalidFlatbuffer::Utf8Error {
error,
range,
error_trace,
} => {
writeln!(
f,
"Utf8 error for string in {:?}: {}\n{}",
range, error, error_trace
)?;
}
InvalidFlatbuffer::MissingNullTerminator { range, error_trace } => {
writeln!(
f,
"String in range [{}, {}) is missing its null terminator.\n{}",
range.start, range.end, error_trace
)?;
}
InvalidFlatbuffer::Unaligned {
position,
unaligned_type,
error_trace,
} => {
writeln!(
f,
"Type `{}` at position {} is unaligned.\n{}",
unaligned_type, position, error_trace
)?;
}
InvalidFlatbuffer::RangeOutOfBounds { range, error_trace } => {
writeln!(
f,
"Range [{}, {}) is out of bounds.\n{}",
range.start, range.end, error_trace
)?;
}
InvalidFlatbuffer::SignedOffsetOutOfBounds {
soffset,
position,
error_trace,
} => {
writeln!(
f,
"Signed offset at position {} has value {} which points out of bounds.\n{}",
position, soffset, error_trace
)?;
}
InvalidFlatbuffer::TooManyTables {} => {
writeln!(f, "Too many tables.")?;
}
InvalidFlatbuffer::ApparentSizeTooLarge {} => {
writeln!(f, "Apparent size too large.")?;
}
InvalidFlatbuffer::DepthLimitReached {} => {
writeln!(f, "Nested table depth limit reached.")?;
}
}
Ok(())
}
}
impl core::fmt::Display for ErrorTrace {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
use ErrorTraceDetail::*;