mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-29 17:37:55 +00:00
Implement fallback to compiling serde_derive from source
This commit is contained in:
@@ -1,25 +1,34 @@
|
||||
[package]
|
||||
name = "serde_derive-x86_64-unknown-linux-gnu"
|
||||
version = "1.0.171-alpha.3"
|
||||
name = "serde_derive"
|
||||
version = "1.0.171"
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
categories = ["no-std", "no-std::no-alloc"]
|
||||
description = "Precompiled implementation of #[derive(Serialize, Deserialize)]"
|
||||
description = "Implementation of #[derive(Serialize, Deserialize)]"
|
||||
documentation = "https://serde.rs/derive.html"
|
||||
edition = "2015"
|
||||
homepage = "https://serde.rs"
|
||||
include = ["serde_derive-x86_64-unknown-linux-gnu", "src"]
|
||||
keywords = ["serde", "serialization", "no_std", "derive"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
readme = "crates-io.md"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
|
||||
[lib]
|
||||
name = "serde_derive"
|
||||
proc-macro = true
|
||||
rust-version = "1.56"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
deserialize_in_place = []
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[target.'cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))'.dependencies]
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = "2.0.25"
|
||||
|
||||
[dev-dependencies]
|
||||
serde = { version = "1", path = "../../serde" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../LICENSE-APACHE
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../LICENSE-MIT
|
||||
@@ -1,16 +0,0 @@
|
||||
```toml
|
||||
# Cargo.toml
|
||||
|
||||
[dependencies]
|
||||
serde = "1" # no features=["derive"]
|
||||
serde_derive-x86_64-unknown-linux-gnu = "1.0.171-alpha.3"
|
||||
```
|
||||
|
||||
```rust
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct MyStruct {
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../README.md
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../crates-io.md
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../serde_derive/src/bound.rs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../serde_derive/src/de.rs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../serde_derive/src/dummy.rs
|
||||
@@ -0,0 +1 @@
|
||||
../../../serde_derive/src/fragment.rs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../serde_derive/src/internals/
|
||||
@@ -1,221 +1,25 @@
|
||||
//! This crate provides Serde's two derive macros.
|
||||
//!
|
||||
//! ```edition2021
|
||||
//! # use serde_derive::{Deserialize, Serialize};
|
||||
//! #
|
||||
//! #[derive(Serialize, Deserialize)]
|
||||
//! # struct S;
|
||||
//! #
|
||||
//! # fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! Please refer to [https://serde.rs/derive.html] for how to set this up.
|
||||
//!
|
||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.171")]
|
||||
#![allow(unknown_lints, bare_trait_objects)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
mod buffer;
|
||||
mod bytecode;
|
||||
|
||||
use crate::buffer::{InputBuffer, OutputBuffer};
|
||||
use crate::bytecode::Bytecode;
|
||||
use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
|
||||
use std::io::{Read, Write};
|
||||
use std::iter::FromIterator;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))]
|
||||
compile_error! {
|
||||
"this proof of concept is only compiled for x86_64-unknown-linux-gnu"
|
||||
}
|
||||
include!("lib_from_source.rs");
|
||||
|
||||
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||
derive(0, input)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Deserialize, attributes(serde))]
|
||||
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||
derive(1 + cfg!(feature = "deserialize_in_place") as u8, input)
|
||||
}
|
||||
|
||||
fn derive(select: u8, input: TokenStream) -> TokenStream {
|
||||
let mut memory = TokenMemory::default();
|
||||
let mut buf = OutputBuffer::new();
|
||||
buf.write_u8(select);
|
||||
|
||||
memory.spans.push(Span::call_site());
|
||||
for token in input {
|
||||
memory.linearize_token(token, &mut buf);
|
||||
}
|
||||
|
||||
let path = concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/serde_derive-x86_64-unknown-linux-gnu",
|
||||
);
|
||||
let mut child = Command::new(path)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("failed to spawn process");
|
||||
|
||||
let mut stdin = child.stdin.take().unwrap();
|
||||
let mut buf = buf.into_bytes();
|
||||
stdin.write_all(&buf).unwrap();
|
||||
drop(stdin);
|
||||
|
||||
let mut stdout = child.stdout.take().unwrap();
|
||||
buf.clear();
|
||||
stdout.read_to_end(&mut buf).unwrap();
|
||||
|
||||
let mut buf = InputBuffer::new(&buf);
|
||||
memory.receive(&mut buf)
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct TokenMemory {
|
||||
spans: Vec<Span>,
|
||||
groups: Vec<Group>,
|
||||
idents: Vec<Ident>,
|
||||
puncts: Vec<Punct>,
|
||||
literals: Vec<Literal>,
|
||||
}
|
||||
|
||||
enum Kind {
|
||||
Group(Delimiter),
|
||||
Ident,
|
||||
Punct(Spacing),
|
||||
Literal,
|
||||
}
|
||||
|
||||
impl TokenMemory {
|
||||
// Depth-first post-order traversal.
|
||||
fn linearize_token(&mut self, token: TokenTree, buf: &mut OutputBuffer) {
|
||||
match token {
|
||||
TokenTree::Group(group) => {
|
||||
let mut len = 0usize;
|
||||
for token in group.stream() {
|
||||
self.linearize_token(token, buf);
|
||||
len += 1;
|
||||
}
|
||||
assert!(len <= u32::MAX as usize);
|
||||
buf.write_u8(match group.delimiter() {
|
||||
Delimiter::Parenthesis => Bytecode::GROUP_PARENTHESIS,
|
||||
Delimiter::Brace => Bytecode::GROUP_BRACE,
|
||||
Delimiter::Bracket => Bytecode::GROUP_BRACKET,
|
||||
Delimiter::None => Bytecode::GROUP_NONE,
|
||||
});
|
||||
buf.write_u32(len as u32);
|
||||
self.spans
|
||||
.extend([group.span(), group.span_open(), group.span_close()]);
|
||||
self.groups.push(group);
|
||||
}
|
||||
TokenTree::Ident(ident) => {
|
||||
buf.write_u8(Bytecode::IDENT);
|
||||
let repr = ident.to_string();
|
||||
assert!(repr.len() <= u16::MAX as usize);
|
||||
buf.write_u16(repr.len() as u16);
|
||||
buf.write_str(&repr);
|
||||
self.spans.push(ident.span());
|
||||
self.idents.push(ident);
|
||||
}
|
||||
TokenTree::Punct(punct) => {
|
||||
buf.write_u8(match punct.spacing() {
|
||||
Spacing::Alone => Bytecode::PUNCT_ALONE,
|
||||
Spacing::Joint => Bytecode::PUNCT_JOINT,
|
||||
});
|
||||
let ch = punct.as_char();
|
||||
assert!(ch.is_ascii());
|
||||
buf.write_u8(ch as u8);
|
||||
self.spans.push(punct.span());
|
||||
self.puncts.push(punct);
|
||||
}
|
||||
TokenTree::Literal(literal) => {
|
||||
buf.write_u8(Bytecode::LITERAL);
|
||||
let repr = literal.to_string();
|
||||
assert!(repr.len() <= u16::MAX as usize);
|
||||
buf.write_u16(repr.len() as u16);
|
||||
buf.write_str(&repr);
|
||||
self.spans.push(literal.span());
|
||||
self.literals.push(literal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn receive(&self, buf: &mut InputBuffer) -> TokenStream {
|
||||
let mut trees = Vec::new();
|
||||
while !buf.is_empty() {
|
||||
match match buf.read_u8() {
|
||||
Bytecode::GROUP_PARENTHESIS => Kind::Group(Delimiter::Parenthesis),
|
||||
Bytecode::GROUP_BRACE => Kind::Group(Delimiter::Brace),
|
||||
Bytecode::GROUP_BRACKET => Kind::Group(Delimiter::Bracket),
|
||||
Bytecode::GROUP_NONE => Kind::Group(Delimiter::None),
|
||||
Bytecode::IDENT => Kind::Ident,
|
||||
Bytecode::PUNCT_ALONE => Kind::Punct(Spacing::Alone),
|
||||
Bytecode::PUNCT_JOINT => Kind::Punct(Spacing::Joint),
|
||||
Bytecode::LITERAL => Kind::Literal,
|
||||
Bytecode::LOAD_GROUP => {
|
||||
let identity = buf.read_u32();
|
||||
let group = self.groups[identity as usize].clone();
|
||||
trees.push(TokenTree::Group(group));
|
||||
continue;
|
||||
}
|
||||
Bytecode::LOAD_IDENT => {
|
||||
let identity = buf.read_u32();
|
||||
let ident = self.idents[identity as usize].clone();
|
||||
trees.push(TokenTree::Ident(ident));
|
||||
continue;
|
||||
}
|
||||
Bytecode::LOAD_PUNCT => {
|
||||
let identity = buf.read_u32();
|
||||
let punct = self.puncts[identity as usize].clone();
|
||||
trees.push(TokenTree::Punct(punct));
|
||||
continue;
|
||||
}
|
||||
Bytecode::LOAD_LITERAL => {
|
||||
let identity = buf.read_u32();
|
||||
let literal = self.literals[identity as usize].clone();
|
||||
trees.push(TokenTree::Literal(literal));
|
||||
continue;
|
||||
}
|
||||
Bytecode::SET_SPAN => {
|
||||
trees.last_mut().unwrap().set_span(self.read_span(buf));
|
||||
continue;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
} {
|
||||
Kind::Group(delimiter) => {
|
||||
let len = buf.read_u32();
|
||||
let stream = trees.drain(trees.len() - len as usize..).collect();
|
||||
let group = Group::new(delimiter, stream);
|
||||
trees.push(TokenTree::Group(group));
|
||||
}
|
||||
Kind::Ident => {
|
||||
let len = buf.read_u16();
|
||||
let repr = buf.read_str(len as usize);
|
||||
let span = self.read_span(buf);
|
||||
let ident = if let Some(repr) = repr.strip_prefix("r#") {
|
||||
Ident::new_raw(repr, span)
|
||||
} else {
|
||||
Ident::new(repr, span)
|
||||
};
|
||||
trees.push(TokenTree::Ident(ident));
|
||||
}
|
||||
Kind::Punct(spacing) => {
|
||||
let ch = buf.read_u8();
|
||||
assert!(ch.is_ascii());
|
||||
let punct = Punct::new(ch as char, spacing);
|
||||
trees.push(TokenTree::Punct(punct));
|
||||
}
|
||||
Kind::Literal => {
|
||||
let len = buf.read_u16();
|
||||
let repr = buf.read_str(len as usize);
|
||||
let literal = Literal::from_str(repr).unwrap();
|
||||
trees.push(TokenTree::Literal(literal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TokenStream::from_iter(trees)
|
||||
}
|
||||
|
||||
fn read_span(&self, buf: &mut InputBuffer) -> Span {
|
||||
let lo = buf.read_u32();
|
||||
let hi = buf.read_u32();
|
||||
let span = self.spans[lo as usize];
|
||||
if lo == hi {
|
||||
span
|
||||
} else {
|
||||
#[cfg(any())] // FIXME
|
||||
return span.join(self.spans[hi as usize]).unwrap_or(span);
|
||||
span
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))]
|
||||
include!("lib_precompiled.rs");
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
#[macro_use]
|
||||
extern crate syn;
|
||||
|
||||
extern crate proc_macro2;
|
||||
|
||||
mod internals;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::DeriveInput;
|
||||
|
||||
#[macro_use]
|
||||
mod bound;
|
||||
#[macro_use]
|
||||
mod fragment;
|
||||
|
||||
mod de;
|
||||
mod dummy;
|
||||
mod pretend;
|
||||
mod ser;
|
||||
mod this;
|
||||
mod try;
|
||||
|
||||
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||
let mut input = parse_macro_input!(input as DeriveInput);
|
||||
ser::expand_derive_serialize(&mut input)
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Deserialize, attributes(serde))]
|
||||
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||
let mut input = parse_macro_input!(input as DeriveInput);
|
||||
de::expand_derive_deserialize(&mut input)
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
.into()
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
mod buffer;
|
||||
mod bytecode;
|
||||
|
||||
use crate::buffer::{InputBuffer, OutputBuffer};
|
||||
use crate::bytecode::Bytecode;
|
||||
use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
|
||||
use std::io::{Read, Write};
|
||||
use std::iter::FromIterator;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||
derive(0, input)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Deserialize, attributes(serde))]
|
||||
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||
derive(1 + cfg!(feature = "deserialize_in_place") as u8, input)
|
||||
}
|
||||
|
||||
fn derive(select: u8, input: TokenStream) -> TokenStream {
|
||||
let mut memory = TokenMemory::default();
|
||||
let mut buf = OutputBuffer::new();
|
||||
buf.write_u8(select);
|
||||
|
||||
memory.spans.push(Span::call_site());
|
||||
for token in input {
|
||||
memory.linearize_token(token, &mut buf);
|
||||
}
|
||||
|
||||
let path = concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/serde_derive-x86_64-unknown-linux-gnu",
|
||||
);
|
||||
let mut child = Command::new(path)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("failed to spawn process");
|
||||
|
||||
let mut stdin = child.stdin.take().unwrap();
|
||||
let mut buf = buf.into_bytes();
|
||||
stdin.write_all(&buf).unwrap();
|
||||
drop(stdin);
|
||||
|
||||
let mut stdout = child.stdout.take().unwrap();
|
||||
buf.clear();
|
||||
stdout.read_to_end(&mut buf).unwrap();
|
||||
|
||||
let mut buf = InputBuffer::new(&buf);
|
||||
memory.receive(&mut buf)
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct TokenMemory {
|
||||
spans: Vec<Span>,
|
||||
groups: Vec<Group>,
|
||||
idents: Vec<Ident>,
|
||||
puncts: Vec<Punct>,
|
||||
literals: Vec<Literal>,
|
||||
}
|
||||
|
||||
enum Kind {
|
||||
Group(Delimiter),
|
||||
Ident,
|
||||
Punct(Spacing),
|
||||
Literal,
|
||||
}
|
||||
|
||||
impl TokenMemory {
|
||||
// Depth-first post-order traversal.
|
||||
fn linearize_token(&mut self, token: TokenTree, buf: &mut OutputBuffer) {
|
||||
match token {
|
||||
TokenTree::Group(group) => {
|
||||
let mut len = 0usize;
|
||||
for token in group.stream() {
|
||||
self.linearize_token(token, buf);
|
||||
len += 1;
|
||||
}
|
||||
assert!(len <= u32::MAX as usize);
|
||||
buf.write_u8(match group.delimiter() {
|
||||
Delimiter::Parenthesis => Bytecode::GROUP_PARENTHESIS,
|
||||
Delimiter::Brace => Bytecode::GROUP_BRACE,
|
||||
Delimiter::Bracket => Bytecode::GROUP_BRACKET,
|
||||
Delimiter::None => Bytecode::GROUP_NONE,
|
||||
});
|
||||
buf.write_u32(len as u32);
|
||||
self.spans
|
||||
.extend([group.span(), group.span_open(), group.span_close()]);
|
||||
self.groups.push(group);
|
||||
}
|
||||
TokenTree::Ident(ident) => {
|
||||
buf.write_u8(Bytecode::IDENT);
|
||||
let repr = ident.to_string();
|
||||
assert!(repr.len() <= u16::MAX as usize);
|
||||
buf.write_u16(repr.len() as u16);
|
||||
buf.write_str(&repr);
|
||||
self.spans.push(ident.span());
|
||||
self.idents.push(ident);
|
||||
}
|
||||
TokenTree::Punct(punct) => {
|
||||
buf.write_u8(match punct.spacing() {
|
||||
Spacing::Alone => Bytecode::PUNCT_ALONE,
|
||||
Spacing::Joint => Bytecode::PUNCT_JOINT,
|
||||
});
|
||||
let ch = punct.as_char();
|
||||
assert!(ch.is_ascii());
|
||||
buf.write_u8(ch as u8);
|
||||
self.spans.push(punct.span());
|
||||
self.puncts.push(punct);
|
||||
}
|
||||
TokenTree::Literal(literal) => {
|
||||
buf.write_u8(Bytecode::LITERAL);
|
||||
let repr = literal.to_string();
|
||||
assert!(repr.len() <= u16::MAX as usize);
|
||||
buf.write_u16(repr.len() as u16);
|
||||
buf.write_str(&repr);
|
||||
self.spans.push(literal.span());
|
||||
self.literals.push(literal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn receive(&self, buf: &mut InputBuffer) -> TokenStream {
|
||||
let mut trees = Vec::new();
|
||||
while !buf.is_empty() {
|
||||
match match buf.read_u8() {
|
||||
Bytecode::GROUP_PARENTHESIS => Kind::Group(Delimiter::Parenthesis),
|
||||
Bytecode::GROUP_BRACE => Kind::Group(Delimiter::Brace),
|
||||
Bytecode::GROUP_BRACKET => Kind::Group(Delimiter::Bracket),
|
||||
Bytecode::GROUP_NONE => Kind::Group(Delimiter::None),
|
||||
Bytecode::IDENT => Kind::Ident,
|
||||
Bytecode::PUNCT_ALONE => Kind::Punct(Spacing::Alone),
|
||||
Bytecode::PUNCT_JOINT => Kind::Punct(Spacing::Joint),
|
||||
Bytecode::LITERAL => Kind::Literal,
|
||||
Bytecode::LOAD_GROUP => {
|
||||
let identity = buf.read_u32();
|
||||
let group = self.groups[identity as usize].clone();
|
||||
trees.push(TokenTree::Group(group));
|
||||
continue;
|
||||
}
|
||||
Bytecode::LOAD_IDENT => {
|
||||
let identity = buf.read_u32();
|
||||
let ident = self.idents[identity as usize].clone();
|
||||
trees.push(TokenTree::Ident(ident));
|
||||
continue;
|
||||
}
|
||||
Bytecode::LOAD_PUNCT => {
|
||||
let identity = buf.read_u32();
|
||||
let punct = self.puncts[identity as usize].clone();
|
||||
trees.push(TokenTree::Punct(punct));
|
||||
continue;
|
||||
}
|
||||
Bytecode::LOAD_LITERAL => {
|
||||
let identity = buf.read_u32();
|
||||
let literal = self.literals[identity as usize].clone();
|
||||
trees.push(TokenTree::Literal(literal));
|
||||
continue;
|
||||
}
|
||||
Bytecode::SET_SPAN => {
|
||||
trees.last_mut().unwrap().set_span(self.read_span(buf));
|
||||
continue;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
} {
|
||||
Kind::Group(delimiter) => {
|
||||
let len = buf.read_u32();
|
||||
let stream = trees.drain(trees.len() - len as usize..).collect();
|
||||
let group = Group::new(delimiter, stream);
|
||||
trees.push(TokenTree::Group(group));
|
||||
}
|
||||
Kind::Ident => {
|
||||
let len = buf.read_u16();
|
||||
let repr = buf.read_str(len as usize);
|
||||
let span = self.read_span(buf);
|
||||
let ident = if let Some(repr) = repr.strip_prefix("r#") {
|
||||
Ident::new_raw(repr, span)
|
||||
} else {
|
||||
Ident::new(repr, span)
|
||||
};
|
||||
trees.push(TokenTree::Ident(ident));
|
||||
}
|
||||
Kind::Punct(spacing) => {
|
||||
let ch = buf.read_u8();
|
||||
assert!(ch.is_ascii());
|
||||
let punct = Punct::new(ch as char, spacing);
|
||||
trees.push(TokenTree::Punct(punct));
|
||||
}
|
||||
Kind::Literal => {
|
||||
let len = buf.read_u16();
|
||||
let repr = buf.read_str(len as usize);
|
||||
let literal = Literal::from_str(repr).unwrap();
|
||||
trees.push(TokenTree::Literal(literal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TokenStream::from_iter(trees)
|
||||
}
|
||||
|
||||
fn read_span(&self, buf: &mut InputBuffer) -> Span {
|
||||
let lo = buf.read_u32();
|
||||
let hi = buf.read_u32();
|
||||
let span = self.spans[lo as usize];
|
||||
if lo == hi {
|
||||
span
|
||||
} else {
|
||||
#[cfg(any())] // FIXME
|
||||
return span.join(self.spans[hi as usize]).unwrap_or(span);
|
||||
span
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../serde_derive/src/pretend.rs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../serde_derive/src/ser.rs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../serde_derive/src/this.rs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../serde_derive/src/try.rs
|
||||
Reference in New Issue
Block a user