New upstream version 1.31.0~beta.4+dfsg1

This commit is contained in:
Ximin Luo 2018-11-03 22:12:17 -07:00
parent 4462d4a060
commit 0bf4aa26bc
6328 changed files with 80410 additions and 37506 deletions

View File

@ -566,7 +566,7 @@ labels to triage issues:
to fix the issue.
* The dark blue **final-comment-period** label marks bugs that are using the
RFC signoff functionality of [rfcbot][rfcbot] and are currenty in the final
RFC signoff functionality of [rfcbot][rfcbot] and are currently in the final
comment period.
* Red, **I**-prefixed labels indicate the **importance** of the issue. The
@ -646,7 +646,7 @@ are:
* Don't be afraid to ask! The Rust community is friendly and helpful.
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
[gdfrustc]: http://manishearth.github.io/rust-internals-docs/rustc/
[gdfrustc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
[gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here
[rif]: http://internals.rust-lang.org
[rr]: https://doc.rust-lang.org/book/README.html

View File

@ -64,9 +64,6 @@ Cargo
- [`cargo run` doesn't require specifying a package in workspaces.][cargo/5877]
- [`cargo doc` now supports `--message-format=json`.][cargo/5878] This is
equivalent to calling `rustdoc --error-format=json`.
- [You can specify which edition to create a project in cargo
with `cargo new --edition`.][cargo/5984] Currently only `2015` is a
valid option.
- [Cargo will now provide a progress bar for builds.][cargo/5995]
Misc
@ -100,9 +97,8 @@ Misc
[54404]: https://github.com/rust-lang/rust/pull/54404/
[cargo/5877]: https://github.com/rust-lang/cargo/pull/5877/
[cargo/5878]: https://github.com/rust-lang/cargo/pull/5878/
[cargo/5984]: https://github.com/rust-lang/cargo/pull/5984/
[cargo/5995]: https://github.com/rust-lang/cargo/pull/5995/
[proc-macros]: https://doc.rust-lang.org/book/2018-edition/ch19-06-macros.html
[proc-macros]: https://doc.rust-lang.org/stable/book/2018-edition/ch19-06-macros.html
[`Ipv4Addr::BROADCAST`]: https://doc.rust-lang.org/nightly/std/net/struct.Ipv4Addr.html#associatedconstant.BROADCAST
[`Ipv4Addr::LOCALHOST`]: https://doc.rust-lang.org/nightly/std/net/struct.Ipv4Addr.html#associatedconstant.LOCALHOST

View File

@ -182,10 +182,9 @@
# Build the profiler runtime
#profiler = false
# Indicates whether the OpenSSL linked into Cargo will be statically linked or
# not. If static linkage is specified then the build system will download a
# known-good version of OpenSSL, compile it, and link it to Cargo.
#openssl-static = false
# Indicates whether the native libraries linked into Cargo will be statically
# linked or not.
#cargo-native-static = false
# Run the build with low priority, by setting the process group's "nice" value
# to +10 on Unix platforms, and by using a "low priority" job object on Windows.
@ -243,19 +242,36 @@
# =============================================================================
[rust]
# Indicates that the build should be optimized for debugging Rust. Note that
# this is typically not what you want as it takes an incredibly large amount of
# time to have a debug-mode rustc compile any code (notably libstd). If this
# value is set to `true` it will affect a number of configuration options below
# as well, if unconfigured.
#debug = false
# Whether or not to optimize the compiler and standard library
# Whether or not to optimize the compiler and standard library.
#
# Note: the slowness of the non optimized compiler compiling itself usually
# outweighs the time gains in not doing optimizations, therefore a
# full bootstrap takes much more time with optimize set to false.
# full bootstrap takes much more time with `optimize` set to false.
#optimize = true
# Indicates that the build should be configured for debugging Rust. A
# `debug`-enabled compiler and standard library will be somewhat
# slower (due to e.g. checking of debug assertions) but should remain
# usable.
#
# Note: If this value is set to `true`, it will affect a number of
# configuration options below as well, if they have been left
# unconfigured in this file.
#
# Note: changes to the `debug` setting do *not* affect `optimize`
# above. In theory, a "maximally debuggable" environment would
# set `optimize` to `false` above to assist the introspection
# facilities of debuggers like lldb and gdb. To recreate such an
# environment, explicitly set `optimize` to `false` and `debug`
# to `true`. In practice, everyone leaves `optimize` set to
# `true`, because an unoptimized rustc with debugging
# enabled becomes *unusably slow* (e.g. rust-lang/rust#24840
# reported a 25x slowdown) and bootstrapping the supposed
# "maximally debuggable" environment (notably libstd) takes
# hours to build.
#
#debug = false
# Number of codegen units to use for each compiler invocation. A value of 0
# means "the number of cores on this machine", and 1+ is passed through to the
# compiler.
@ -322,6 +338,7 @@
# Flag indicating whether codegen tests will be run or not. If you get an error
# saying that the FileCheck executable is missing, you may want to disable this.
# Also see the target's llvm-filecheck option.
#codegen-tests = true
# Flag indicating whether git info will be retrieved from .git automatically.
@ -416,6 +433,10 @@
# target.
#llvm-config = "../path/to/llvm/root/bin/llvm-config"
# Normally the build system can find LLVM's FileCheck utility, but if
# not, you can specify an explicit file name for it.
#llvm-filecheck = "/path/to/FileCheck"
# Path to the custom jemalloc static library to link into the standard library
# by default. This is only used if jemalloc is still enabled above
#jemalloc = "/path/to/jemalloc/libjemalloc_pic.a"
@ -476,3 +497,7 @@
# as the one built on Windows will contain backslashes in paths causing problems
# on linux
#src-tarball = true
#
# Whether to allow failures when building tools
#missing-tools = false

View File

@ -1 +1 @@
da5f414c2c0bfe5198934493f04c676e2b23ff2e
04da282bb42d12e4e6fa0ee2742f3c7c95866773

639
src/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -64,3 +64,4 @@ rustc-workspace-hack = { path = 'tools/rustc-workspace-hack' }
[patch."https://github.com/rust-lang-nursery/rust-clippy"]
clippy_lints = { path = "tools/clippy/clippy_lints" }
rustc_tools_util = { path = "tools/clippy/rustc_tools_util" }

View File

@ -287,10 +287,6 @@ fn main() {
cmd.arg("--cfg").arg("parallel_queries");
}
if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() {
cmd.arg("-Z").arg("verify-llvm-ir");
}
if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none()
{
cmd.arg("-Dwarnings");

View File

@ -594,7 +594,7 @@ class RustBuild(object):
return ''
def bootstrap_binary(self):
"""Return the path of the boostrap binary
"""Return the path of the bootstrap binary
>>> rb = RustBuild()
>>> rb.build_dir = "build"
@ -844,6 +844,11 @@ def bootstrap(help_triggered):
def main():
"""Entry point for the bootstrap process"""
start_time = time()
# x.py help <cmd> ...
if len(sys.argv) > 1 and sys.argv[1] == 'help':
sys.argv = sys.argv[:1] + [sys.argv[2], '-h'] + sys.argv[3:]
help_triggered = (
'-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1)
try:

View File

@ -379,7 +379,6 @@ impl<'a> Builder<'a> {
test::Ui,
test::RunPass,
test::CompileFail,
test::ParseFail,
test::RunFail,
test::RunPassValgrind,
test::MirOpt,
@ -1000,10 +999,6 @@ impl<'a> Builder<'a> {
cargo.env("RUSTC_BACKTRACE_ON_ICE", "1");
}
if self.config.rust_verify_llvm_ir {
cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
}
cargo.env("RUSTC_VERBOSE", self.verbosity.to_string());
// in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful.

View File

@ -169,19 +169,21 @@ impl Ord for Interned<String> {
}
}
struct TyIntern<T> {
struct TyIntern<T: Hash + Clone + Eq> {
items: Vec<T>,
set: HashMap<T, Interned<T>>,
}
impl<T: Hash + Clone + Eq> TyIntern<T> {
fn new() -> TyIntern<T> {
impl<T: Hash + Clone + Eq> Default for TyIntern<T> {
fn default() -> Self {
TyIntern {
items: Vec::new(),
set: HashMap::new(),
set: Default::default(),
}
}
}
impl<T: Hash + Clone + Eq> TyIntern<T> {
fn intern_borrow<B>(&mut self, item: &B) -> Interned<T>
where
B: Eq + Hash + ToOwned<Owned=T> + ?Sized,
@ -212,19 +214,13 @@ impl<T: Hash + Clone + Eq> TyIntern<T> {
}
}
#[derive(Default)]
pub struct Interner {
strs: Mutex<TyIntern<String>>,
paths: Mutex<TyIntern<PathBuf>>,
}
impl Interner {
fn new() -> Interner {
Interner {
strs: Mutex::new(TyIntern::new()),
paths: Mutex::new(TyIntern::new()),
}
}
pub fn intern_str(&self, s: &str) -> Interned<String> {
self.strs.lock().unwrap().intern_borrow(s)
}
@ -238,7 +234,7 @@ impl Interner {
}
lazy_static! {
pub static ref INTERNER: Interner = Interner::new();
pub static ref INTERNER: Interner = Interner::default();
}
/// This is essentially a HashMap which allows storing any type in its input and

View File

@ -24,7 +24,7 @@ use Build;
use config::Config;
// The version number
pub const CFG_RELEASE_NUM: &str = "1.30.0";
pub const CFG_RELEASE_NUM: &str = "1.31.0";
pub struct GitInfo {
inner: Option<Info>,

View File

@ -224,7 +224,8 @@ impl Step for Rustdoc {
target,
"check",
"src/tools/rustdoc",
SourceType::InTree);
SourceType::InTree,
&[]);
let _folder = builder.fold_output(|| format!("stage{}-rustdoc", compiler.stage));
println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);

View File

@ -249,7 +249,7 @@ impl Step for StdLink {
fn copy_apple_sanitizer_dylibs(builder: &Builder, native_dir: &Path, platform: &str, into: &Path) {
for &sanitizer in &["asan", "tsan"] {
let filename = format!("libclang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
let filename = format!("lib__rustc__clang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
let mut src_path = native_dir.join(sanitizer);
src_path.push("build");
src_path.push("lib");
@ -569,6 +569,9 @@ pub fn rustc_cargo_env(builder: &Builder, cargo: &mut Command) {
if builder.config.rustc_parallel_queries {
cargo.env("RUSTC_PARALLEL_QUERIES", "1");
}
if builder.config.rust_verify_llvm_ir {
cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]

View File

@ -134,6 +134,7 @@ pub struct Config {
pub test_miri: bool,
pub save_toolstates: Option<PathBuf>,
pub print_step_timings: bool,
pub missing_tools: bool,
// Fallback musl-root for all targets
pub musl_root: Option<PathBuf>,
@ -148,7 +149,7 @@ pub struct Config {
pub nodejs: Option<PathBuf>,
pub gdb: Option<PathBuf>,
pub python: Option<PathBuf>,
pub openssl_static: bool,
pub cargo_native_static: bool,
pub configure_args: Vec<String>,
// These are either the stage0 downloaded binaries or the locally installed ones.
@ -162,6 +163,8 @@ pub struct Config {
pub struct Target {
/// Some(path to llvm-config) if using an external LLVM.
pub llvm_config: Option<PathBuf>,
/// Some(path to FileCheck) if one was specified.
pub llvm_filecheck: Option<PathBuf>,
pub jemalloc: Option<PathBuf>,
pub cc: Option<PathBuf>,
pub cxx: Option<PathBuf>,
@ -218,7 +221,7 @@ struct Build {
verbose: Option<usize>,
sanitizers: Option<bool>,
profiler: Option<bool>,
openssl_static: Option<bool>,
cargo_native_static: Option<bool>,
configure_args: Option<Vec<String>>,
local_rebuild: Option<bool>,
print_step_timings: Option<bool>,
@ -269,6 +272,7 @@ struct Dist {
gpg_password_file: Option<String>,
upload_addr: Option<String>,
src_tarball: Option<bool>,
missing_tools: Option<bool>,
}
#[derive(Deserialize)]
@ -330,6 +334,7 @@ struct Rust {
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct TomlTarget {
llvm_config: Option<String>,
llvm_filecheck: Option<String>,
jemalloc: Option<String>,
cc: Option<String>,
cxx: Option<String>,
@ -372,6 +377,7 @@ impl Config {
config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")];
config.rust_codegen_backends_dir = "codegen-backends".to_owned();
config.deny_warnings = true;
config.missing_tools = false;
// set by bootstrap.py
config.build = INTERNER.intern_str(&env::var("BUILD").expect("'BUILD' to be set"));
@ -424,7 +430,7 @@ impl Config {
}
}).unwrap_or_else(|| TomlConfig::default());
let build = toml.build.clone().unwrap_or(Build::default());
let build = toml.build.clone().unwrap_or_default();
// set by bootstrap.py
config.hosts.push(config.build.clone());
for host in build.host.iter() {
@ -468,7 +474,7 @@ impl Config {
set(&mut config.verbose, build.verbose);
set(&mut config.sanitizers, build.sanitizers);
set(&mut config.profiler, build.profiler);
set(&mut config.openssl_static, build.openssl_static);
set(&mut config.cargo_native_static, build.cargo_native_static);
set(&mut config.configure_args, build.configure_args);
set(&mut config.local_rebuild, build.local_rebuild);
set(&mut config.print_step_timings, build.print_step_timings);
@ -518,7 +524,7 @@ impl Config {
set(&mut config.llvm_link_shared, llvm.link_shared);
config.llvm_targets = llvm.targets.clone();
config.llvm_experimental_targets = llvm.experimental_targets.clone()
.unwrap_or("WebAssembly;RISCV".to_string());
.unwrap_or_else(|| "WebAssembly;RISCV".to_string());
config.llvm_link_jobs = llvm.link_jobs;
config.llvm_version_suffix = llvm.version_suffix.clone();
config.llvm_clang_cl = llvm.clang_cl.clone();
@ -583,6 +589,9 @@ impl Config {
if let Some(ref s) = cfg.llvm_config {
target.llvm_config = Some(config.src.join(s));
}
if let Some(ref s) = cfg.llvm_filecheck {
target.llvm_filecheck = Some(config.src.join(s));
}
if let Some(ref s) = cfg.jemalloc {
target.jemalloc = Some(config.src.join(s));
}
@ -607,6 +616,7 @@ impl Config {
config.dist_gpg_password_file = t.gpg_password_file.clone().map(PathBuf::from);
config.dist_upload_addr = t.upload_addr.clone();
set(&mut config.rust_dist_src, t.src_tarball);
set(&mut config.missing_tools, t.missing_tools);
}
// Now that we've reached the end of our configuration, infer the
@ -618,6 +628,9 @@ impl Config {
let default = false;
config.llvm_assertions = llvm_assertions.unwrap_or(default);
let default = true;
config.rust_optimize = optimize.unwrap_or(default);
let default = match &config.channel[..] {
"stable" | "beta" | "nightly" => true,
_ => false,
@ -630,7 +643,6 @@ impl Config {
config.debug_jemalloc = debug_jemalloc.unwrap_or(default);
config.rust_debuginfo = debuginfo.unwrap_or(default);
config.rust_debug_assertions = debug_assertions.unwrap_or(default);
config.rust_optimize = optimize.unwrap_or(!default);
let default = config.channel == "dev";
config.ignore_git = ignore_git.unwrap_or(default);

View File

@ -64,11 +64,12 @@ o("locked-deps", "build.locked-deps", "force Cargo.lock to be up to date")
o("vendor", "build.vendor", "enable usage of vendored Rust crates")
o("sanitizers", "build.sanitizers", "build the sanitizer runtimes (asan, lsan, msan, tsan)")
o("dist-src", "rust.dist-src", "when building tarballs enables building a source tarball")
o("cargo-openssl-static", "build.openssl-static", "static openssl in cargo")
o("cargo-native-static", "build.cargo-native-static", "static native libraries in cargo")
o("profiler", "build.profiler", "build the profiler runtime")
o("emscripten", None, "compile the emscripten backend as well as LLVM")
o("full-tools", None, "enable all tools")
o("lldb", "rust.lldb", "build lldb")
o("missing-tools", "dist.missing-tools", "allow failures when building tools")
# Optimization and debugging options. These may be overridden by the release
# channel, etc.
@ -95,6 +96,8 @@ v("docdir", "install.docdir", "install documentation in PATH")
v("bindir", "install.bindir", "install binaries")
v("llvm-root", None, "set LLVM root")
v("llvm-config", None, "set path to llvm-config")
v("llvm-filecheck", None, "set path to LLVM's FileCheck utility")
v("python", "build.python", "set path to python")
v("jemalloc-root", None, "set directory where libjemalloc_pic.a is located")
v("android-cross-path", "target.arm-linux-androideabi.android-ndk",
@ -323,6 +326,10 @@ for key in known_args:
set('build.cargo', value + '/bin/cargo')
elif option.name == 'llvm-root':
set('target.{}.llvm-config'.format(build()), value + '/bin/llvm-config')
elif option.name == 'llvm-config':
set('target.{}.llvm-config'.format(build()), value)
elif option.name == 'llvm-filecheck':
set('target.{}.llvm-filecheck'.format(build()), value)
elif option.name == 'jemalloc-root':
set('target.{}.jemalloc'.format(build()), value + '/libjemalloc_pic.a')
elif option.name == 'tools':

View File

@ -31,7 +31,6 @@ use channel;
use util::{libdir, is_dylib, exe};
use builder::{Builder, RunConfig, ShouldRun, Step};
use compile;
use native;
use tool::{self, Tool};
use cache::{INTERNER, Interned};
use time;
@ -67,6 +66,14 @@ fn rust_installer(builder: &Builder) -> Command {
builder.tool_cmd(Tool::RustInstaller)
}
fn missing_tool(tool_name: &str, skip: bool) {
if skip {
println!("Unable to build {}, skipping dist", tool_name)
} else {
panic!("Unable to build {}", tool_name)
}
}
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Docs {
pub stage: u32,
@ -982,12 +989,6 @@ impl Step for PlainSourceTarball {
.arg("--debug")
.arg("--vers").arg(CARGO_VENDOR_VERSION)
.arg("cargo-vendor");
if let Some(dir) = builder.openssl_install_dir(builder.config.build) {
builder.ensure(native::Openssl {
target: builder.config.build,
});
cmd.env("OPENSSL_DIR", dir);
}
builder.run(&mut cmd);
}
@ -1166,7 +1167,7 @@ impl Step for Rls {
let rls = builder.ensure(tool::Rls {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build RLS, skipping dist"); None })?;
}).or_else(|| { missing_tool("RLS", builder.build.config.missing_tools); None })?;
builder.install(&rls, &image.join("bin"), 0o755);
let doc = image.join("share/doc/rls");
@ -1245,24 +1246,26 @@ impl Step for Clippy {
let clippy = builder.ensure(tool::Clippy {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build clippy, skipping dist"); None })?;
}).or_else(|| { missing_tool("clippy", builder.build.config.missing_tools); None })?;
let cargoclippy = builder.ensure(tool::CargoClippy {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build cargo clippy, skipping dist"); None })?;
}).or_else(|| { missing_tool("cargo clippy", builder.build.config.missing_tools); None })?;
builder.install(&clippy, &image.join("bin"), 0o755);
builder.install(&cargoclippy, &image.join("bin"), 0o755);
let doc = image.join("share/doc/clippy");
builder.install(&src.join("README.md"), &doc, 0o644);
builder.install(&src.join("LICENSE"), &doc, 0o644);
builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
// Prepare the overlay
let overlay = tmp.join("clippy-overlay");
drop(fs::remove_dir_all(&overlay));
t!(fs::create_dir_all(&overlay));
builder.install(&src.join("README.md"), &overlay, 0o644);
builder.install(&src.join("LICENSE"), &doc, 0o644);
builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
builder.create(&overlay.join("version"), &version);
// Generate the installer tarball
@ -1324,11 +1327,11 @@ impl Step for Rustfmt {
let rustfmt = builder.ensure(tool::Rustfmt {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build Rustfmt, skipping dist"); None })?;
}).or_else(|| { missing_tool("Rustfmt", builder.build.config.missing_tools); None })?;
let cargofmt = builder.ensure(tool::Cargofmt {
compiler: builder.compiler(stage, builder.config.build),
target, extra_features: Vec::new()
}).or_else(|| { println!("Unable to build Cargofmt, skipping dist"); None })?;
}).or_else(|| { missing_tool("Cargofmt", builder.build.config.missing_tools); None })?;
builder.install(&rustfmt, &image.join("bin"), 0o755);
builder.install(&cargofmt, &image.join("bin"), 0o755);
@ -1444,8 +1447,8 @@ impl Step for Extended {
tarballs.extend(rls_installer.clone());
tarballs.extend(clippy_installer.clone());
tarballs.extend(rustfmt_installer.clone());
tarballs.extend(llvm_tools_installer.clone());
tarballs.extend(lldb_installer.clone());
tarballs.extend(llvm_tools_installer);
tarballs.extend(lldb_installer);
tarballs.push(analysis_installer);
tarballs.push(std_installer);
if builder.config.docs {

View File

@ -805,6 +805,7 @@ impl Step for Rustdoc {
"doc",
"src/tools/rustdoc",
SourceType::InTree,
&[]
);
cargo.env("RUSTDOCFLAGS", "--document-private-items");

View File

@ -278,10 +278,6 @@ pub struct Build {
initial_rustc: PathBuf,
initial_cargo: PathBuf,
// Probed tools at runtime
lldb_version: Option<String>,
lldb_python_dir: Option<String>,
// Runtime state filled in later on
// C/C++ compilers and archiver for all targets
cc: HashMap<Interned<String>, cc::Tool>,
@ -416,8 +412,6 @@ impl Build {
ar: HashMap::new(),
ranlib: HashMap::new(),
crates: HashMap::new(),
lldb_version: None,
lldb_python_dir: None,
is_sudo,
ci_env: CiEnv::current(),
delayed_failures: RefCell::new(Vec::new()),
@ -641,9 +635,28 @@ impl Build {
/// Returns the path to `FileCheck` binary for the specified target
fn llvm_filecheck(&self, target: Interned<String>) -> PathBuf {
let target_config = self.config.target_config.get(&target);
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
if let Some(s) = target_config.and_then(|c| c.llvm_filecheck.as_ref()) {
s.to_path_buf()
} else if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
let llvm_bindir = output(Command::new(s).arg("--bindir"));
Path::new(llvm_bindir.trim()).join(exe("FileCheck", &*target))
let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", &*target));
if filecheck.exists() {
filecheck
} else {
// On Fedora the system LLVM installs FileCheck in the
// llvm subdirectory of the libdir.
let llvm_libdir = output(Command::new(s).arg("--libdir"));
let lib_filecheck = Path::new(llvm_libdir.trim())
.join("llvm").join(exe("FileCheck", &*target));
if lib_filecheck.exists() {
lib_filecheck
} else {
// Return the most normal file name, even though
// it doesn't exist, so that any error message
// refers to that.
filecheck
}
}
} else {
let base = self.llvm_out(self.config.build).join("build");
let base = if !self.config.ninja && self.config.build.contains("msvc") {
@ -752,7 +765,7 @@ impl Build {
let path = match which {
GitRepo::Rustc => {
let sha = self.rust_info.sha().expect("failed to find sha");
let sha = self.rust_sha().unwrap_or(channel::CFG_RELEASE_NUM);
format!("/rustc/{}", sha)
}
GitRepo::Llvm => format!("/rustc/llvm"),
@ -913,25 +926,6 @@ impl Build {
(self.hosts.iter().any(|h| *h == target) || target == self.build)
}
/// Returns the directory that OpenSSL artifacts are compiled into if
/// configured to do so.
fn openssl_dir(&self, target: Interned<String>) -> Option<PathBuf> {
// OpenSSL not used on Windows
if target.contains("windows") {
None
} else if self.config.openssl_static {
Some(self.out.join(&*target).join("openssl"))
} else {
None
}
}
/// Returns the directory that OpenSSL artifacts are installed into if
/// configured as such.
fn openssl_install_dir(&self, target: Interned<String>) -> Option<PathBuf> {
self.openssl_dir(target).map(|p| p.join("install"))
}
/// Given `num` in the form "a.b.c" return a "release string" which
/// describes the release version number.
///
@ -1275,6 +1269,9 @@ impl Build {
t!(fs::create_dir_all(dstdir));
drop(fs::remove_file(&dst));
{
if !src.exists() {
panic!("Error: File \"{}\" not found!", src.display());
}
let mut s = t!(fs::File::open(&src));
let mut d = t!(fs::File::create(&dst));
io::copy(&mut s, &mut d).expect("failed to copy");

View File

@ -531,189 +531,3 @@ impl Step for TestHelpers {
.compile("rust_test_helpers");
}
}
const OPENSSL_VERS: &'static str = "1.0.2n";
const OPENSSL_SHA256: &'static str =
"370babb75f278c39e0c50e8c4e7493bc0f18db6867478341a832a982fd15a8fe";
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Openssl {
pub target: Interned<String>,
}
impl Step for Openssl {
type Output = ();
fn should_run(run: ShouldRun) -> ShouldRun {
run.never()
}
fn run(self, builder: &Builder) {
if builder.config.dry_run {
return;
}
let target = self.target;
let out = match builder.openssl_dir(target) {
Some(dir) => dir,
None => return,
};
let stamp = out.join(".stamp");
let mut contents = String::new();
drop(File::open(&stamp).and_then(|mut f| f.read_to_string(&mut contents)));
if contents == OPENSSL_VERS {
return
}
t!(fs::create_dir_all(&out));
let name = format!("openssl-{}.tar.gz", OPENSSL_VERS);
let tarball = out.join(&name);
if !tarball.exists() {
let tmp = tarball.with_extension("tmp");
// originally from https://www.openssl.org/source/...
let url = format!("https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/{}",
name);
let mut last_error = None;
for _ in 0..3 {
let status = Command::new("curl")
.arg("-o").arg(&tmp)
.arg("-f") // make curl fail if the URL does not return HTTP 200
.arg(&url)
.status()
.expect("failed to spawn curl");
// Retry if download failed.
if !status.success() {
last_error = Some(status.to_string());
continue;
}
// Ensure the hash is correct.
let mut shasum = if target.contains("apple") ||
builder.config.build.contains("netbsd") {
let mut cmd = Command::new("shasum");
cmd.arg("-a").arg("256");
cmd
} else {
Command::new("sha256sum")
};
let output = output(&mut shasum.arg(&tmp));
let found = output.split_whitespace().next().unwrap();
// If the hash is wrong, probably the download is incomplete or S3 served an error
// page. In any case, retry.
if found != OPENSSL_SHA256 {
last_error = Some(format!(
"downloaded openssl sha256 different\n\
expected: {}\n\
found: {}\n",
OPENSSL_SHA256,
found
));
continue;
}
// Everything is fine, so exit the retry loop.
last_error = None;
break;
}
if let Some(error) = last_error {
panic!("failed to download openssl source: {}", error);
}
t!(fs::rename(&tmp, &tarball));
}
let obj = out.join(format!("openssl-{}", OPENSSL_VERS));
let dst = builder.openssl_install_dir(target).unwrap();
drop(fs::remove_dir_all(&obj));
drop(fs::remove_dir_all(&dst));
builder.run(Command::new("tar").arg("zxf").arg(&tarball).current_dir(&out));
let mut configure = Command::new("perl");
configure.arg(obj.join("Configure"));
configure.arg(format!("--prefix={}", dst.display()));
configure.arg("no-dso");
configure.arg("no-ssl2");
configure.arg("no-ssl3");
let os = match &*target {
"aarch64-linux-android" => "linux-aarch64",
"aarch64-unknown-linux-gnu" => "linux-aarch64",
"aarch64-unknown-linux-musl" => "linux-aarch64",
"aarch64-unknown-netbsd" => "BSD-generic64",
"arm-linux-androideabi" => "android",
"arm-unknown-linux-gnueabi" => "linux-armv4",
"arm-unknown-linux-gnueabihf" => "linux-armv4",
"armv6-unknown-netbsd-eabihf" => "BSD-generic32",
"armv7-linux-androideabi" => "android-armv7",
"armv7-unknown-linux-gnueabihf" => "linux-armv4",
"armv7-unknown-netbsd-eabihf" => "BSD-generic32",
"i586-unknown-linux-gnu" => "linux-elf",
"i586-unknown-linux-musl" => "linux-elf",
"i686-apple-darwin" => "darwin-i386-cc",
"i686-linux-android" => "android-x86",
"i686-unknown-freebsd" => "BSD-x86-elf",
"i686-unknown-linux-gnu" => "linux-elf",
"i686-unknown-linux-musl" => "linux-elf",
"i686-unknown-netbsd" => "BSD-x86-elf",
"mips-unknown-linux-gnu" => "linux-mips32",
"mips64-unknown-linux-gnuabi64" => "linux64-mips64",
"mips64el-unknown-linux-gnuabi64" => "linux64-mips64",
"mipsel-unknown-linux-gnu" => "linux-mips32",
"powerpc-unknown-linux-gnu" => "linux-ppc",
"powerpc-unknown-linux-gnuspe" => "linux-ppc",
"powerpc-unknown-netbsd" => "BSD-generic32",
"powerpc64-unknown-linux-gnu" => "linux-ppc64",
"powerpc64le-unknown-linux-gnu" => "linux-ppc64le",
"powerpc64le-unknown-linux-musl" => "linux-ppc64le",
"s390x-unknown-linux-gnu" => "linux64-s390x",
"sparc-unknown-linux-gnu" => "linux-sparcv9",
"sparc64-unknown-linux-gnu" => "linux64-sparcv9",
"sparc64-unknown-netbsd" => "BSD-sparc64",
"x86_64-apple-darwin" => "darwin64-x86_64-cc",
"x86_64-linux-android" => "linux-x86_64",
"x86_64-unknown-freebsd" => "BSD-x86_64",
"x86_64-unknown-dragonfly" => "BSD-x86_64",
"x86_64-unknown-linux-gnu" => "linux-x86_64",
"x86_64-unknown-linux-gnux32" => "linux-x32",
"x86_64-unknown-linux-musl" => "linux-x86_64",
"x86_64-unknown-netbsd" => "BSD-x86_64",
_ => panic!("don't know how to configure OpenSSL for {}", target),
};
configure.arg(os);
configure.env("CC", builder.cc(target));
for flag in builder.cflags(target, GitRepo::Rustc) {
configure.arg(flag);
}
// There is no specific os target for android aarch64 or x86_64,
// so we need to pass some extra cflags
if target == "aarch64-linux-android" || target == "x86_64-linux-android" {
configure.arg("-mandroid");
configure.arg("-fomit-frame-pointer");
}
if target == "sparc64-unknown-netbsd" {
// Need -m64 to get assembly generated correctly for sparc64.
configure.arg("-m64");
if builder.config.build.contains("netbsd") {
// Disable sparc64 asm on NetBSD builders, it uses
// m4(1)'s -B flag, which NetBSD m4 does not support.
configure.arg("no-asm");
}
}
// Make PIE binaries
// Non-PIE linker support was removed in Lollipop
// https://source.android.com/security/enhancements/enhancements50
if target == "i686-linux-android" {
configure.arg("no-asm");
}
configure.current_dir(&obj);
builder.info(&format!("Configuring openssl for {}", target));
builder.run_quiet(&mut configure);
builder.info(&format!("Building openssl for {}", target));
builder.run_quiet(Command::new("make").arg("-j1").current_dir(&obj));
builder.info(&format!("Installing openssl for {}", target));
builder.run_quiet(Command::new("make").arg("install").arg("-j1").current_dir(&obj));
let mut f = t!(File::create(&stamp));
t!(f.write_all(OPENSSL_VERS.as_bytes()));
}
}

View File

@ -236,19 +236,6 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
}
}
let run = |cmd: &mut Command| {
cmd.output().map(|output| {
String::from_utf8_lossy(&output.stdout)
.lines().next().unwrap_or_else(|| {
panic!("{:?} failed {:?}", cmd, output)
}).to_string()
})
};
build.lldb_version = run(Command::new("lldb").arg("--version")).ok();
if build.lldb_version.is_some() {
build.lldb_python_dir = run(Command::new("lldb").arg("-P")).ok();
}
if let Some(ref s) = build.config.ccache {
cmd_finder.must_have(s);
}

View File

@ -228,7 +228,8 @@ impl Step for Cargo {
self.host,
"test",
"src/tools/cargo",
SourceType::Submodule);
SourceType::Submodule,
&[]);
if !builder.fail_fast {
cargo.arg("--no-fail-fast");
@ -290,7 +291,8 @@ impl Step for Rls {
host,
"test",
"src/tools/rls",
SourceType::Submodule);
SourceType::Submodule,
&[]);
// Copy `src/tools/rls/test_data` to a writable drive.
let test_workspace_path = builder.out.join("rls-test-data");
@ -352,7 +354,8 @@ impl Step for Rustfmt {
host,
"test",
"src/tools/rustfmt",
SourceType::Submodule);
SourceType::Submodule,
&[]);
let dir = testdir(builder, compiler.host);
t!(fs::create_dir_all(&dir));
@ -407,7 +410,8 @@ impl Step for Miri {
host,
"test",
"src/tools/miri",
SourceType::Submodule);
SourceType::Submodule,
&[]);
// miri tests need to know about the stage sysroot
cargo.env("MIRI_SYSROOT", builder.sysroot(compiler));
@ -466,7 +470,8 @@ impl Step for Clippy {
host,
"test",
"src/tools/clippy",
SourceType::Submodule);
SourceType::Submodule,
&[]);
// clippy tests need to know about the stage sysroot
cargo.env("SYSROOT", builder.sysroot(compiler));
@ -755,10 +760,11 @@ default_test_with_compare_mode!(Ui {
compare_mode: "nll"
});
default_test!(RunPass {
default_test_with_compare_mode!(RunPass {
path: "src/test/run-pass",
mode: "run-pass",
suite: "run-pass"
suite: "run-pass",
compare_mode: "nll"
});
default_test!(CompileFail {
@ -767,12 +773,6 @@ default_test!(CompileFail {
suite: "compile-fail"
});
default_test!(ParseFail {
path: "src/test/parse-fail",
mode: "parse-fail",
suite: "parse-fail"
});
default_test!(RunFail {
path: "src/test/run-fail",
mode: "run-fail",
@ -811,8 +811,7 @@ default_test!(Incremental {
default_test!(Debuginfo {
path: "src/test/debuginfo",
// What this runs varies depending on the native platform being apple
mode: "debuginfo-XXX",
mode: "debuginfo",
suite: "debuginfo"
});
@ -949,18 +948,11 @@ impl Step for Compiletest {
return;
}
if mode == "debuginfo-XXX" {
return if builder.config.build.contains("apple") {
builder.ensure(Compiletest {
mode: "debuginfo-lldb",
..self
});
} else {
builder.ensure(Compiletest {
mode: "debuginfo-gdb",
..self
});
};
if mode == "debuginfo" {
return builder.ensure(Compiletest {
mode: "debuginfo-both",
..self
});
}
builder.ensure(dist::DebuggerScripts {
@ -1060,7 +1052,7 @@ impl Step for Compiletest {
let hostflags = flags.clone();
cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
let mut targetflags = flags.clone();
let mut targetflags = flags;
targetflags.push(format!(
"-Lnative={}",
builder.test_helpers_out(target).display()
@ -1081,11 +1073,34 @@ impl Step for Compiletest {
if let Some(ref gdb) = builder.config.gdb {
cmd.arg("--gdb").arg(gdb);
}
if let Some(ref vers) = builder.lldb_version {
let run = |cmd: &mut Command| {
cmd.output().map(|output| {
String::from_utf8_lossy(&output.stdout)
.lines().next().unwrap_or_else(|| {
panic!("{:?} failed {:?}", cmd, output)
}).to_string()
})
};
let lldb_exe = if builder.config.lldb_enabled && !target.contains("emscripten") {
// Test against the lldb that was just built.
builder.llvm_out(target)
.join("bin")
.join("lldb")
} else {
PathBuf::from("lldb")
};
let lldb_version = Command::new(&lldb_exe)
.arg("--version")
.output()
.map(|output| { String::from_utf8_lossy(&output.stdout).to_string() })
.ok();
if let Some(ref vers) = lldb_version {
cmd.arg("--lldb-version").arg(vers);
}
if let Some(ref dir) = builder.lldb_python_dir {
cmd.arg("--lldb-python-dir").arg(dir);
let lldb_python_dir = run(Command::new(&lldb_exe).arg("-P")).ok();
if let Some(ref dir) = lldb_python_dir {
cmd.arg("--lldb-python-dir").arg(dir);
}
}
// Get paths from cmd args
@ -1761,7 +1776,8 @@ impl Step for CrateRustdoc {
target,
test_kind.subcommand(),
"src/tools/rustdoc",
SourceType::InTree);
SourceType::InTree,
&[]);
if test_kind.subcommand() == "test" && !builder.fail_fast {
cargo.arg("--no-fail-fast");
}

View File

@ -80,8 +80,8 @@ impl Step for ToolBuild {
"build",
path,
self.source_type,
&self.extra_features,
);
cargo.arg("--features").arg(self.extra_features.join(" "));
let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
builder.info(&format!("Building stage{} tool {} ({})", compiler.stage, tool, target));
@ -208,6 +208,7 @@ pub fn prepare_tool_cargo(
command: &'static str,
path: &'static str,
source_type: SourceType,
extra_features: &[String],
) -> Command {
let mut cargo = builder.cargo(compiler, mode, target, command);
let dir = builder.src.join(path);
@ -221,10 +222,16 @@ pub fn prepare_tool_cargo(
cargo.env("RUSTC_EXTERNAL_TOOL", "1");
}
if let Some(dir) = builder.openssl_install_dir(target) {
cargo.env("OPENSSL_STATIC", "1");
cargo.env("OPENSSL_DIR", dir);
cargo.env("LIBZ_SYS_STATIC", "1");
let mut features = extra_features.iter().cloned().collect::<Vec<_>>();
if builder.build.config.cargo_native_static {
if path.ends_with("cargo") ||
path.ends_with("rls") ||
path.ends_with("clippy") ||
path.ends_with("rustfmt")
{
cargo.env("LIBZ_SYS_STATIC", "1");
features.push("rustc-workspace-hack/all-static".to_string());
}
}
// if tools are using lzma we want to force the build script to build its
@ -244,6 +251,9 @@ pub fn prepare_tool_cargo(
if let Some(date) = info.commit_date() {
cargo.env("CFG_COMMIT_DATE", date);
}
if features.len() > 0 {
cargo.arg("--features").arg(&features.join(", "));
}
cargo
}
@ -439,6 +449,7 @@ impl Step for Rustdoc {
"build",
"src/tools/rustdoc",
SourceType::InTree,
&[],
);
// Most tools don't get debuginfo, but rustdoc should.
@ -495,9 +506,6 @@ impl Step for Cargo {
}
fn run(self, builder: &Builder) -> PathBuf {
builder.ensure(native::Openssl {
target: self.target,
});
// Cargo depends on procedural macros, which requires a full host
// compiler to be available, so we need to depend on that.
builder.ensure(compile::Rustc {
@ -597,9 +605,6 @@ tool_extended!((self, builder),
if clippy.is_some() {
self.extra_features.push("clippy".to_owned());
}
builder.ensure(native::Openssl {
target: self.target,
});
// RLS depends on procedural macros, which requires a full host
// compiler to be available, so we need to depend on that.
builder.ensure(compile::Rustc {

View File

@ -91,13 +91,13 @@ pub fn try_run_suppressed(cmd: &mut Command) -> bool {
output.status.success()
}
pub fn gnu_target(target: &str) -> String {
pub fn gnu_target(target: &str) -> &str {
match target {
"i686-pc-windows-msvc" => "i686-pc-win32".to_string(),
"x86_64-pc-windows-msvc" => "x86_64-pc-win32".to_string(),
"i686-pc-windows-gnu" => "i686-w64-mingw32".to_string(),
"x86_64-pc-windows-gnu" => "x86_64-w64-mingw32".to_string(),
s => s.to_string(),
"i686-pc-windows-msvc" => "i686-pc-win32",
"x86_64-pc-windows-msvc" => "x86_64-pc-win32",
"i686-pc-windows-gnu" => "i686-w64-mingw32",
"x86_64-pc-windows-gnu" => "x86_64-w64-mingw32",
s => s,
}
}
@ -178,6 +178,37 @@ pub struct NativeLibBoilerplate {
pub out_dir: PathBuf,
}
impl NativeLibBoilerplate {
/// On OSX we don't want to ship the exact filename that compiler-rt builds.
/// This conflicts with the system and ours is likely a wildly different
/// version, so they can't be substituted.
///
/// As a result, we rename it here but we need to also use
/// `install_name_tool` on OSX to rename the commands listed inside of it to
/// ensure it's linked against correctly.
pub fn fixup_sanitizer_lib_name(&self, sanitizer_name: &str) {
if env::var("TARGET").unwrap() != "x86_64-apple-darwin" {
return
}
let dir = self.out_dir.join("build/lib/darwin");
let name = format!("clang_rt.{}_osx_dynamic", sanitizer_name);
let src = dir.join(&format!("lib{}.dylib", name));
let new_name = format!("lib__rustc__{}.dylib", name);
let dst = dir.join(&new_name);
println!("{} => {}", src.display(), dst.display());
fs::rename(&src, &dst).unwrap();
let status = Command::new("install_name_tool")
.arg("-id")
.arg(format!("@rpath/{}", new_name))
.arg(&dst)
.status()
.expect("failed to execute `install_name_tool`");
assert!(status.success());
}
}
impl Drop for NativeLibBoilerplate {
fn drop(&mut self) {
if !thread::panicking() {
@ -202,7 +233,8 @@ pub fn native_lib_boilerplate(
let src_dir = current_dir.join("..").join(src_name);
rerun_if_changed_anything_in_dir(&src_dir);
let out_dir = env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or(env::var_os("OUT_DIR").unwrap());
let out_dir = env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or_else(||
env::var_os("OUT_DIR").unwrap());
let out_dir = PathBuf::from(out_dir).join(out_name);
t!(fs::create_dir_all(&out_dir));
if link_name.contains('=') {
@ -229,7 +261,7 @@ pub fn native_lib_boilerplate(
pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
-> Result<(NativeLibBoilerplate, String), ()>
{
let (link_name, search_path, dynamic) = match &*env::var("TARGET").unwrap() {
let (link_name, search_path, apple) = match &*env::var("TARGET").unwrap() {
"x86_64-unknown-linux-gnu" => (
format!("clang_rt.{}-x86_64", sanitizer_name),
"build/lib/linux",
@ -242,8 +274,8 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
),
_ => return Err(()),
};
let to_link = if dynamic {
format!("dylib={}", link_name)
let to_link = if apple {
format!("dylib=__rustc__{}", link_name)
} else {
format!("static={}", link_name)
};

View File

@ -83,6 +83,11 @@ RUN ./build-git.sh
COPY dist-x86_64-linux/build-headers.sh /tmp/
RUN ./build-headers.sh
# OpenSSL requires a more recent version of perl
# with so we install newer ones here
COPY dist-x86_64-linux/build-perl.sh /tmp/
RUN ./build-perl.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
@ -110,3 +115,5 @@ ENV CFLAGS -mstackrealign
# When we build cargo in this container, we don't want it to use the system
# libcurl, instead it should compile its own.
ENV LIBCURL_NO_PKG_CONFIG 1
ENV DIST_REQUIRE_ALL_TOOLS 1

View File

@ -83,6 +83,11 @@ RUN ./build-git.sh
COPY dist-x86_64-linux/build-headers.sh /tmp/
RUN ./build-headers.sh
# OpenSSL requires a more recent version of perl
# with so we install newer ones here
COPY dist-x86_64-linux/build-perl.sh /tmp/
RUN ./build-perl.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
@ -106,3 +111,5 @@ ENV DIST_SRC 1
# When we build cargo in this container, we don't want it to use the system
# libcurl, instead it should compile its own.
ENV LIBCURL_NO_PKG_CONFIG 1
ENV DIST_REQUIRE_ALL_TOOLS 1

View File

@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Copyright 2018 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
set -ex
source shared.sh
curl https://www.cpan.org/src/5.0/perl-5.28.0.tar.gz | \
tar xzf -
cd perl-5.28.0
# Gotta do some hackery to tell python about our custom OpenSSL build, but other
# than that fairly normal.
CC=gcc \
CFLAGS='-I /rustroot/include' LDFLAGS='-L /rustroot/lib -L /rustroot/lib64' \
hide_output ./configure.gnu
hide_output make -j10
hide_output make install
cd ..
rm -rf perl-5.28.0

View File

@ -32,17 +32,11 @@ shift
export CFLAGS="-fPIC $CFLAGS"
# FIXME: remove the patch when updating to 1.1.20
MUSL=musl-1.1.19
MUSL=musl-1.1.20
# may have been downloaded in a previous run
if [ ! -d $MUSL ]; then
curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
# Patch to fix https://github.com/rust-lang/rust/issues/48967
cd $MUSL && \
curl "https://git.musl-libc.org/cgit/musl/patch/?id=610c5a8524c3d6cd3ac5a5f1231422e7648a3791" |\
patch -p1 && \
cd -
fi
cd $MUSL

View File

@ -36,7 +36,6 @@ ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \
src/test/ui \
src/test/run-pass \
src/test/compile-fail \
src/test/parse-fail \
src/test/mir-opt \
src/test/codegen-units \
src/libcore \

View File

@ -39,7 +39,7 @@ fi
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-sccache"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-openssl-static"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-native-static"
if [ "$DIST_SRC" = "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src"
@ -51,7 +51,7 @@ fi
#
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
# either automatically or manually.
export RUST_RELEASE_CHANNEL=stable
export RUST_RELEASE_CHANNEL=beta
if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
@ -61,6 +61,7 @@ if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
elif [ "$DEPLOY_ALT" != "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
fi
else
# We almost always want debug assertions enabled, but sometimes this takes too
@ -74,6 +75,12 @@ else
if [ "$NO_LLVM_ASSERTIONS" = "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions"
fi
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
fi
if [ "$RUST_RELEASE_CHANNEL" = "nightly" ] || [ "$DIST_REQUIRE_ALL_TOOLS" = "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-missing-tools"
fi
# We've had problems in the past of shell scripts leaking fds into the sccache

View File

@ -1,32 +0,0 @@
# Rust documentations
## Building
To generate all the docs, follow the "Building Documentation" instructions in
the README in the root of the repository. This will convert the distributed
Markdown docs to HTML and generate HTML doc for the books, 'std' and 'extra'
libraries.
To generate HTML documentation from one source file/crate, do something like:
~~~~text
rustdoc --output html-doc/ --output-format html ../src/libstd/path.rs
~~~~
(This, of course, requires a working build of the `rustdoc` tool.)
## Additional notes
To generate an HTML version of a doc from Markdown manually, you can do
something like:
~~~~text
rustdoc reference.md
~~~~
(`reference.md` being the Rust Reference Manual.)
An overview of how to use the `rustdoc` command is available [in the docs][1].
Further details are available from the command line by with `rustdoc --help`.
[1]: https://github.com/rust-lang/rust/blob/master/src/doc/rustdoc/src/what-is-rustdoc.md

View File

@ -1,3 +1,7 @@
[book]
title = "The Rust Programming Language"
author = "Steve Klabnik and Carol Nichols, with Contributions from the Rust Community"
[output.html]
additional-css = ["ferris.css", "src/theme/2018-edition.css"]
additional-js = ["ferris.js"]

View File

@ -0,0 +1,33 @@
body.light .does_not_compile,
body.light .panics,
body.light .not_desired_behavior,
body.rust .does_not_compile,
body.rust .panics,
body.rust .not_desired_behavior {
background: #fff1f1;
}
body.coal .does_not_compile,
body.coal .panics,
body.coal .not_desired_behavior,
body.navy .does_not_compile,
body.navy .panics,
body.navy .not_desired_behavior,
body.ayu .does_not_compile,
body.ayu .panics,
body.ayu .not_desired_behavior {
background: #501f21;
}
.ferris {
position: absolute;
z-index: 99;
right: 5px;
top: 30px;
width: 10%;
height: auto;
}
.ferris-explain {
width: 100px;
}

View File

@ -0,0 +1,51 @@
var ferrisTypes = [
{
attr: 'does_not_compile',
title: 'This code does not compile!'
},
{
attr: 'panics',
title: 'This code panics!'
},
{
attr: 'unsafe',
title: 'This code block contains unsafe code.'
},
{
attr: 'not_desired_behavior',
title: 'This code does not produce the desired behavior.'
}
]
document.addEventListener('DOMContentLoaded', () => {
for (var ferrisType of ferrisTypes) {
attachFerrises(ferrisType)
}
})
function attachFerrises (type) {
var elements = document.getElementsByClassName(type.attr)
for (var codeBlock of elements) {
var lines = codeBlock.textContent.split(/\r|\r\n|\n/).length - 1;
if (lines >= 4) {
attachFerris(codeBlock, type)
}
}
}
function attachFerris (element, type) {
var a = document.createElement('a')
a.setAttribute('href', 'ch00-00-introduction.html#ferris')
a.setAttribute('target', '_blank')
var img = document.createElement('img')
img.setAttribute('src', 'img/ferris/' + type.attr + '.svg')
img.setAttribute('title', type.title)
img.className = 'ferris'
a.appendChild(img)
element.parentElement.insertBefore(a, element)
}

View File

@ -36,10 +36,9 @@
## Basic Rust Literacy
- [Modules](ch07-00-modules.md)
- [`mod` and the Filesystem](ch07-01-mod-and-the-filesystem.md)
- [Controlling Visibility with `pub`](ch07-02-controlling-visibility-with-pub.md)
- [Referring to Names in Different Modules](ch07-03-importing-names-with-use.md)
- [Packages, Crates, and Modules](ch07-00-packages-crates-and-modules.md)
- [Packages and crates for making libraries and executables](ch07-01-packages-and-crates-for-making-libraries-and-executables.md)
- [Modules and `use` to control scope and privacy](ch07-02-modules-and-use-to-control-scope-and-privacy.md)
- [Common Collections](ch08-00-common-collections.md)
- [Vectors](ch08-01-vectors.md)
@ -116,6 +115,7 @@
- [Advanced Traits](ch19-03-advanced-traits.md)
- [Advanced Types](ch19-04-advanced-types.md)
- [Advanced Functions & Closures](ch19-05-advanced-functions-and-closures.md)
- [Macros](ch19-06-macros.md)
- [Final Project: Building a Multithreaded Web Server](ch20-00-final-project-a-web-server.md)
- [A Single Threaded Web Server](ch20-01-single-threaded.md)
@ -130,3 +130,4 @@
- [E - Translations](appendix-05-translation.md)
- [F - How Rust is Made and “Nightly Rust”](appendix-06-nightly-rust.md)
- [G - Other useful tools](appendix-07-other-useful-tools.md)
- [H - Editions](appendix-08-editions.md)

View File

@ -25,6 +25,85 @@ you both `rustc` and `cargo`. To take any Cargo project and format it:
$ cargo fmt
```
## Fix up your code with `rustfix`
If youve written code in Rust before, youve probably seen a compiler
warning before. For example, consider this code:
```rust
fn do_something() {}
fn main() {
for i in 0..100 {
do_something();
}
}
```
Here, were calling do_something a hundred times. But we never use the
variable i. And so Rust warns:
```text
> cargo build
Compiling myprogram v0.1.0 (file:///projects/myprogram)
warning: unused variable: `i`
--> src\main.rs:4:9
|
4 | for i in 1..100 {
| ^ help: consider using `_i` instead
|
= note: #[warn(unused_variables)] on by default
Finished dev [unoptimized + debuginfo] target(s) in 0.50s
```
See how it suggests that we use `_i` as a name instead? We can automatically
apply that suggestion with cargo fix:
```console
> cargo fix
Checking myprogram v0.1.0 (file:///projects/myprogram)
Fixing src\main.rs (1 fix)
Finished dev [unoptimized + debuginfo] target(s) in 0.59s
```
If we look at `src\main.rs` again, well see that the code has changed:
```rust
fn do_something() {}
fn main() {
for _i in 0..100 {
do_something();
}
}
```
Were now using `_i`, and the warning will no longer appear.
`cargo fix` can also be used to transition your code between different editions
of Rust. Editions are covered in Appendix H.
## More lints with `clippy`
`clippy` is a bunch of lints to catch common mistakes and improve your Rust
code.
`clippy` is not at 1.0 yet, but a preview is available for you to use in the
meantime. Please give it a try and let us know how it goes!
To install `clippy`:
```shell
$ rustup component add clippy-preview
```
To take any Cargo project and run clippy's lints on it:
```shell
$ cargo clippy
```
## IDE integration with the Rust Language Server
To help IDE integration, the Rust project distributes `rls`, the Rust

View File

@ -0,0 +1,58 @@
# Appendix H - Editions
Way back in Chapter 1, we saw that `cargo new` adds a bit of metadata to your
`Cargo.toml` about an `edition`. We can finally talk about what that means!
In Appendix F, we talked about Rust's six-week release cycle. This means that
users get a constant stream of new features. This is much faster than updates
for other languages, but this also means that each update is smaller. After a
while, all of those tiny changes add up. But, from release to release, it can
be hard to look back and say "Wow, between Rust 1.10 and Rust 1.31, Rust has
changed a lot!"
Every two or three years, the Rust team produces a new *edition* of Rust.
Each edition brings together the features that have landed into a clear
package, with fully updated documentation and tooling. New editions ship
through the usual release process.
This serves different purposes for different people:
* For active Rust users, it brings together incremental changes into an
easy-to-understand package.
* For non-users, it signals that some major advancements have landed, which
might make Rust worth another look.
* For those developing Rust itself, it provides a rallying point for the
project as a whole.
At the time of writing, there are two editions: Rust 2015, and Rust 2018.
This book assumes Rust 2018; see the "second edition" for Rust 2015 specific
details.
## Compatibility
Speaking of there being multiple editions, the `edition = "2018"` key in
`Cargo.toml` indicates which edition your code should be compiled under. If
the key does not exist, it defaults to `2015`, for backwards compatibility
reasons.
This opt in enables editions to contain incompatible changes, like adding a
new keyword that might conflict with identifiers in code, or turning warnings
into errors. A Rust compiler will support all editions that existed prior to
the compiler's release, and can link crates of any supported editions
together. Edition changes only affect the way the compiler initially parses
the code. Therefore, if you're using Rust 2015, and one of your dependencies
uses Rust 2018, it all works just fine. The opposite situation works as well.
Just to be clear: most features will be available on all editions. People
using any edition of Rust will continue to see improvements as new stable
releases are made. In some cases however, mainly when new keywords are added,
but sometimes for other reasons, there may be new features that are only
available in later editions. You only need to upgrade if you want to take
advantage of such features.
## Read More
For more details, the [Edition
Guide](https://rust-lang-nursery.github.io/edition-guide/) is a complete
book about editions, including how to automatically upgrade your code to
a new edition via `cargo fix`.

View File

@ -162,18 +162,29 @@ There is no wrong way to read this book: if you want to skip ahead, go for it!
You might have to jump back to earlier chapters if you experience any
confusion. But do whatever works for you.
<span id="ferris"></span>
An important part of the process of learning Rust is learning how to read the
error messages the compiler displays: these will guide you toward working code.
As such, well provide many examples of code that doesnt compile along with
the error message the compiler will show you in each situation. Know that if
you enter and run a random example, it may not compile! Make sure you read the
surrounding text to see whether the example youre trying to run is meant to
error. In most situations, well lead you to the correct version of any code
that doesnt compile.
error. Ferris will also help you distinguish code that isn't meant to work:
| Ferris | Meaning |
|------------------------------------------------------------------------|--------------------------------------------------|
| <img src="img/ferris/does_not_compile.svg" class="ferris-explain"> | This code does not compile! |
| <img src="img/ferris/panics.svg" class="ferris-explain"> | This code panics! |
| <img src="img/ferris/unsafe.svg" class="ferris-explain"> | This code block contains unsafe code. |
| <img src="img/ferris/not_desired_behavior.svg" class="ferris-explain"> | This code does not produce the desired behavior. |
In most situations, well lead you to the correct version of any code that
doesnt compile.
## Source Code
The source files from which this book is generated can be found on
[GitHub][book].
[book]: https://github.com/rust-lang/book/tree/master/second-edition/src
[book]: https://github.com/rust-lang/book/tree/master/2018-edition/src

View File

@ -60,6 +60,7 @@ code in Listing 1-2.
name = "hello_cargo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2018"
[dependencies]
```
@ -76,10 +77,11 @@ The first line, `[package]`, is a section heading that indicates that the
following statements are configuring a package. As we add more information to
this file, well add other sections.
The next three lines set the configuration information Cargo needs to compile
The next four lines set the configuration information Cargo needs to compile
your program: the name, the version, and who wrote it. Cargo gets your name and
email information from your environment, so if that information is not correct,
fix the information now and then save the file.
fix the information now and then save the file. We'll talk about the `edition`
key in Appendix H.
The last line, `[dependencies]`, is the start of a section for you to list any
of your projects dependencies. In Rust, packages of code are referred to as

View File

@ -360,9 +360,10 @@ library. However, the Rust team does provide a [`rand` crate][randcrate].
### Using a Crate to Get More Functionality
Remember that a crate is a package of Rust code. The project weve been
building is a *binary crate*, which is an executable. The `rand` crate is a
*library crate*, which contains code intended to be used in other programs.
Remember that a crate is a collection of Rust source code files.
The project weve been building is a *binary crate*, which is an executable.
The `rand` crate is a *library crate*, which contains code intended to be
used in other programs.
Cargos use of external crates is where it really shines. Before we can write
code that uses `rand`, we need to modify the *Cargo.toml* file to include the
@ -603,7 +604,7 @@ will explain.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
extern crate rand;
use std::io;

View File

@ -10,12 +10,46 @@ Specifically, youll learn about variables, basic types, functions, comments,
and control flow. These foundations will be in every Rust program, and learning
them early will give you a strong core to start from.
> ### Keywords
>
> The Rust language has a set of *keywords* that are reserved for use by
> the language only, much as in other languages. Keep in mind that you cannot
> use these words as names of variables or functions. Most of the keywords have
> special meanings, and youll be using them to do various tasks in your Rust
> programs; a few have no current functionality associated with them but have
> been reserved for functionality that might be added to Rust in the future. You
> can find a list of the keywords in Appendix A.
## Keywords
The Rust language has a set of *keywords* that are reserved for use by
the language only, much as in other languages. Keep in mind that you cannot
use these words as names of variables or functions. Most of the keywords have
special meanings, and youll be using them to do various tasks in your Rust
programs; a few have no current functionality associated with them but have
been reserved for functionality that might be added to Rust in the future. You
can find a list of the keywords in Appendix A.
## Identifiers
We're going to be explaining a bunch of concepts in this book: variables,
functions, structs, lots of things. All of these things need names. A name
in Rust is called an "identifier," and can be made up of any nonempty ASCII
string, with some restrictions:
Either:
* The first character is a letter.
* The remaining characters are alphanumeric or _.
or:
* The first character is _.
* The identifier is more than one character. _ alone is not an identifier.
* The remaining characters are alphanumeric or _.
### Raw identifiers
Sometimes, you may need to use a name that's a keyword for another purpose.
Maybe you need to call a function named *match* that is coming from a C
library, where 'match' is not a keyword. To do this, you can use a "raw identifier."
Raw identifiers start with `#r`:
```rust,ignore
let r#fn = "this variable is named 'fn' even though that's a keyword";
// call a function named 'match'
r#match();
```
You won't need raw identifiers often, but when you do, you *really* need them.

View File

@ -16,7 +16,7 @@ code with the following code that wont compile just yet:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let x = 5;
println!("The value of x is: {}", x);
@ -207,7 +207,7 @@ from having to come up with different names, such as `spaces_str` and
`spaces_num`; instead, we can reuse the simpler `spaces` name. However, if we
try to use `mut` for this, as shown here, well get a compile-time error:
```rust,ignore
```rust,ignore,does_not_compile
let mut spaces = " ";
spaces = spaces.len();
```

View File

@ -362,7 +362,7 @@ compile but exit with an error when it runs:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,panics
fn main() {
let a = [1, 2, 3, 4, 5];
let index = 10;

View File

@ -170,7 +170,7 @@ to another variable, as the following code tries to do; youll get an error:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let x = (let y = 6);
}
@ -308,7 +308,7 @@ expression to a statement, well get an error.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let x = plus_one(5);

View File

@ -78,7 +78,7 @@ the condition isnt a `bool`, well get an error. For example:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let number = 3;
@ -212,7 +212,7 @@ example, well get an error:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let condition = true;

View File

@ -319,7 +319,7 @@ considers `s1` to no longer be valid and, therefore, Rust doesnt need to free
anything when `s1` goes out of scope. Check out what happens when you try to
use `s1` after `s2` is created; it wont work:
```rust,ignore
```rust,ignore,does_not_compile
let s1 = String::from("hello");
let s2 = s1;

View File

@ -83,7 +83,7 @@ Listing 4-6. Spoiler alert: it doesnt work!
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let s = String::from("hello");
@ -140,25 +140,27 @@ fail:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
println!("{}, {}", r1, r2);
```
Heres the error:
```text
error[E0499]: cannot borrow `s` as mutable more than once at a time
--> borrow_twice.rs:5:19
--> src/main.rs:5:10
|
4 | let r1 = &mut s;
| - first mutable borrow occurs here
5 | let r2 = &mut s;
| ^ second mutable borrow occurs here
6 | }
| - first borrow ends here
4 | let r1 = &mut s;
| ------ first mutable borrow occurs here
5 | let r2 = &mut s;
| ^^^^^^ second mutable borrow occurs here
6 | println!("{}, {}", r1, r2);
| -- borrow later used here
```
This restriction allows for mutation but in a very controlled fashion. Its
@ -194,28 +196,30 @@ let r2 = &mut s;
A similar rule exists for combining mutable and immutable references. This code
results in an error:
```rust,ignore
```rust,ignore,does_not_compile
let mut s = String::from("hello");
let r1 = &s; // no problem
let r2 = &s; // no problem
let r3 = &mut s; // BIG PROBLEM
println!("{}, {}, and {}", r1, r2, r3);
```
Heres the error:
```text
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as
immutable
--> borrow_thrice.rs:6:19
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
--> src/main.rs:6:10
|
4 | let r1 = &s; // no problem
| - immutable borrow occurs here
5 | let r2 = &s; // no problem
6 | let r3 = &mut s; // BIG PROBLEM
| ^ mutable borrow occurs here
7 | }
| - immutable borrow ends here
4 | let r1 = &s; // no problem
| -- immutable borrow occurs here
5 | let r2 = &s; // no problem
6 | let r3 = &mut s; // BIG PROBLEM
| ^^^^^^ mutable borrow occurs here
7 |
8 | println!("{}, {}, and {}", r1, r2, r3);
| -- borrow later used here
```
Whew! We *also* cannot have a mutable reference while we have an immutable one.
@ -244,7 +248,7 @@ compile-time error:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let reference_to_nothing = dangle();
}

View File

@ -265,13 +265,15 @@ compile time error:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let mut s = String::from("hello world");
let word = first_word(&s);
s.clear(); // Error!
println!("the first word is: {}", word);
}
```
@ -279,15 +281,16 @@ Heres the compiler error:
```text
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
--> src/main.rs:6:5
|
4 | let word = first_word(&s);
| - immutable borrow occurs here
5 |
6 | s.clear(); // Error!
| ^ mutable borrow occurs here
7 | }
| - immutable borrow ends here
--> src/main.rs:10:5
|
8 | let word = first_word(&s);
| -- immutable borrow occurs here
9 |
10 | s.clear(); // Error!
| ^^^^^^^^^ mutable borrow occurs here
11 |
12 | println!("the first word is: {}", word);
| ---- borrow later used here
```
Recall from the borrowing rules that if we have an immutable reference to

View File

@ -271,7 +271,7 @@ itself. Well discuss traits in Chapter 10.
>
> <span class="filename">Filename: src/main.rs</span>
>
> ```rust,ignore
> ```rust,ignore,does_not_compile
> struct User {
> username: &str,
> email: &str,

View File

@ -148,7 +148,7 @@ work, however:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
struct Rectangle {
width: u32,
height: u32,

View File

@ -339,7 +339,7 @@ types, the compiler wont let us use an `Option<T>` value as if it were
definitely a valid value. For example, this code wont compile because its
trying to add an `i8` to an `Option<i8>`:
```rust,ignore
```rust,ignore,does_not_compile
let x: i8 = 5;
let y: Option<i8> = Some(5);

View File

@ -239,7 +239,7 @@ consistently a user favorite.
Theres one other aspect of `match` we need to discuss. Consider this version
of our `plus_one` function that has a bug and wont compile:
```rust,ignore
```rust,ignore,does_not_compile
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
Some(i) => Some(i + 1),

View File

@ -1,24 +0,0 @@
# Using Modules to Reuse and Organize Code
When you start writing programs in Rust, your code might live solely in the
`main` function. As your code grows, youll eventually move functionality into
other functions for reuse and better organization. By splitting your code into
smaller chunks, you make each chunk easier to understand on its own. But what
happens if you have too many functions? Rust has a module system that enables
the reuse of code in an organized fashion.
In the same way that you extract lines of code into a function, you can extract
functions (and other code, like structs and enums) into different modules. A
*module* is a namespace that contains definitions of functions or types, and
you can choose whether those definitions are visible outside their module
(public) or not (private). Heres an overview of how modules work:
* The `mod` keyword declares a new module. Code within the module appears
either immediately following this declaration within curly brackets or in
another file.
* By default, functions, types, constants, and modules are private. The `pub`
keyword makes an item public and therefore visible outside its namespace.
* The `use` keyword brings modules, or the definitions inside modules, into
scope so its easier to refer to them.
Well look at each of these parts to see how they fit into the whole.

View File

@ -0,0 +1,15 @@
# Packages, Crates, and Modules
A key question when writing programs is scope: what names do I know about?
What functions am I allowed to call? What does this variable refer to?
Rust has a number of features related to scopes. This is sometimes called
"the module system", but it encompases more than just modules:
* A *path* is a way of naming something.
* *Modules* and the *use keyword* let you control the scope and privacy of paths.
* *Crates* are a tree of modules that produce a library or executable.
* *Packages* are a Cargo feature that let you build, test, and share crates.
This chapter will cover all of these concepts. You'll be importing and
exporting things like a pro soon!

View File

@ -1,480 +0,0 @@
## `mod` and the Filesystem
Well start our module example by making a new project with Cargo, but instead
of creating a binary crate, well make a library crate: a project that other
people can pull into their projects as a dependency. For example, the `rand`
crate discussed in Chapter 2 is a library crate that we used as a dependency in
the guessing game project.
Well create a skeleton of a library that provides some general networking
functionality; well concentrate on the organization of the modules and
functions, but we wont worry about what code goes in the function bodies.
Well call our library `communicator`. To create a library, pass the `--lib`
option:
```text
$ cargo new communicator --lib
$ cd communicator
```
Notice that Cargo generated *src/lib.rs* instead of *src/main.rs*. Inside
*src/lib.rs* well find the following:
<span class="filename">Filename: src/lib.rs</span>
```rust
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
```
Cargo creates an example test to help us get our library started. Well
look at the `#[]` and `mod tests` syntax in the “Using `super` to Access a
Parent Module” section later in this chapter, but for now, leave this code at
the bottom of *src/lib.rs*.
Because we dont have a *src/main.rs* file, theres nothing for Cargo to
execute with the `cargo run` command. Therefore, well use the `cargo build`
command to compile our library crates code.
Well look at different options for organizing your librarys code that will be
suitable in a variety of situations, depending on the intent of the code.
### Module Definitions
For our `communicator` networking library, well first define a module named
`network` that contains the definition of a function called `connect`. Every
module definition in Rust starts with the `mod` keyword. Add this code to the
beginning of the *src/lib.rs* file, above the test code:
<span class="filename">Filename: src/lib.rs</span>
```rust
mod network {
fn connect() {
}
}
```
After the `mod` keyword, we put the name of the module, `network`, and then a
block of code in curly brackets. Everything inside this block is inside the
namespace `network`. In this case, we have a single function, `connect`. If we
wanted to call this function from code outside the `network` module, we
would need to specify the module and use the namespace syntax `::` like so:
`network::connect()`.
We can also have multiple modules, side by side, in the same *src/lib.rs* file.
For example, to also have a `client` module that has a function named
`connect`, we can add it as shown in Listing 7-1:
<span class="filename">Filename: src/lib.rs</span>
```rust
mod network {
fn connect() {
}
}
mod client {
fn connect() {
}
}
```
<span class="caption">Listing 7-1: The `network` module and the `client` module
defined side by side in *src/lib.rs*</span>
Now we have a `network::connect` function and a `client::connect` function.
These can have completely different functionality, and the function names do
not conflict with each other because theyre in different modules.
In this case, because were building a library, the file that serves as the
entry point for building our library is *src/lib.rs*. However, in respect to
creating modules, theres nothing special about *src/lib.rs*. We could also
create modules in *src/main.rs* for a binary crate in the same way as were
creating modules in *src/lib.rs* for the library crate. In fact, we can put
modules inside of modules, which can be useful as your modules grow to keep
related functionality organized together and separate functionality apart. The
way you choose to organize your code depends on how you think about the
relationship between the parts of your code. For instance, the `client` code
and its `connect` function might make more sense to users of our library if
they were inside the `network` namespace instead, as in Listing 7-2:
<span class="filename">Filename: src/lib.rs</span>
```rust
mod network {
fn connect() {
}
mod client {
fn connect() {
}
}
}
```
<span class="caption">Listing 7-2: Moving the `client` module inside the
`network` module</span>
In your *src/lib.rs* file, replace the existing `mod network` and `mod client`
definitions with the ones in Listing 7-2, which have the `client` module as an
inner module of `network`. The functions `network::connect` and
`network::client::connect` are both named `connect`, but they dont conflict
with each other because theyre in different namespaces.
In this way, modules form a hierarchy. The contents of *src/lib.rs* are at the
topmost level, and the submodules are at lower levels. Heres what the
organization of our example in Listing 7-1 looks like when thought of as a
hierarchy:
```text
communicator
├── network
└── client
```
And heres the hierarchy corresponding to the example in Listing 7-2:
```text
communicator
└── network
└── client
```
The hierarchy shows that in Listing 7-2, `client` is a child of the `network`
module rather than a sibling. More complicated projects can have many modules,
and theyll need to be organized logically in order for you to keep track of
them. What “logically” means in your project is up to you and depends on how
you and your librarys users think about your projects domain. Use the
techniques shown here to create side-by-side modules and nested modules in
whatever structure you would like.
### Moving Modules to Other Files
Modules form a hierarchical structure, much like another structure in computing
that youre used to: filesystems! We can use Rusts module system along with
multiple files to split up Rust projects so not everything lives in
*src/lib.rs* or *src/main.rs*. For this example, lets start with the code in
Listing 7-3:
<span class="filename">Filename: src/lib.rs</span>
```rust
mod client {
fn connect() {
}
}
mod network {
fn connect() {
}
mod server {
fn connect() {
}
}
}
```
<span class="caption">Listing 7-3: Three modules, `client`, `network`, and
`network::server`, all defined in *src/lib.rs*</span>
The file *src/lib.rs* has this module hierarchy:
```text
communicator
├── client
└── network
└── server
```
If these modules had many functions, and those functions were becoming lengthy,
it would be difficult to scroll through this file to find the code we wanted to
work with. Because the functions are nested inside one or more `mod` blocks,
the lines of code inside the functions will start getting lengthy as well.
These would be good reasons to separate the `client`, `network`, and `server`
modules from *src/lib.rs* and place them into their own files.
First, lets replace the `client` module code with only the declaration of the
`client` module so that *src/lib.rs* looks like code shown in Listing 7-4:
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
mod client;
mod network {
fn connect() {
}
mod server {
fn connect() {
}
}
}
```
<span class="caption">Listing 7-4: Extracting the contents of the `client` module but leaving the declaration in *src/lib.rs*</span>
Were still *declaring* the `client` module here, but by replacing the block
with a semicolon, were telling Rust to look in another location for the code
defined within the scope of the `client` module. In other words, the line `mod
client;` means this:
```rust,ignore
mod client {
// contents of client.rs
}
```
Now we need to create the external file with that module name. Create a
*client.rs* file in your *src/* directory and open it. Then enter the
following, which is the `connect` function in the `client` module that we
removed in the previous step:
<span class="filename">Filename: src/client.rs</span>
```rust
fn connect() {
}
```
Note that we dont need a `mod` declaration in this file because we already
declared the `client` module with `mod` in *src/lib.rs*. This file just
provides the *contents* of the `client` module. If we put a `mod client` here,
wed be giving the `client` module its own submodule named `client`!
Rust only knows to look in *src/lib.rs* by default. If we want to add more
files to our project, we need to tell Rust in *src/lib.rs* to look in other
files; this is why `mod client` needs to be defined in *src/lib.rs* and cant
be defined in *src/client.rs*.
Now the project should compile successfully, although youll get a few
warnings. Remember to use `cargo build` instead of `cargo run` because we have
a library crate rather than a binary crate:
```text
$ cargo build
Compiling communicator v0.1.0 (file:///projects/communicator)
warning: function is never used: `connect`
--> src/client.rs:1:1
|
1 | / fn connect() {
2 | | }
| |_^
|
= note: #[warn(dead_code)] on by default
warning: function is never used: `connect`
--> src/lib.rs:4:5
|
4 | / fn connect() {
5 | | }
| |_____^
warning: function is never used: `connect`
--> src/lib.rs:8:9
|
8 | / fn connect() {
9 | | }
| |_________^
```
These warnings tell us that we have functions that are never used. Dont worry
about these warnings for now; well address them later in this chapter in the
“Controlling Visibility with `pub`” section. The good news is that theyre just
warnings; our project built successfully!
Next, lets extract the `network` module into its own file using the same
pattern. In *src/lib.rs*, delete the body of the `network` module and add a
semicolon to the declaration, like so:
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
mod client;
mod network;
```
Then create a new *src/network.rs* file and enter the following:
<span class="filename">Filename: src/network.rs</span>
```rust
fn connect() {
}
mod server {
fn connect() {
}
}
```
Notice that we still have a `mod` declaration within this module file; this is
because we still want `server` to be a submodule of `network`.
Run `cargo build` again. Success! We have one more module to extract: `server`.
Because its a submodule—that is, a module within a module—our current tactic
of extracting a module into a file named after that module wont work. Well
try anyway so you can see the error. First, change *src/network.rs* to have
`mod server;` instead of the `server` modules contents:
<span class="filename">Filename: src/network.rs</span>
```rust,ignore
fn connect() {
}
mod server;
```
Then create a *src/server.rs* file and enter the contents of the `server`
module that we extracted:
<span class="filename">Filename: src/server.rs</span>
```rust
fn connect() {
}
```
When we try to `cargo build`, well get the error shown in Listing 7-5:
```text
$ cargo build
Compiling communicator v0.1.0 (file:///projects/communicator)
error: cannot declare a new module at this location
--> src/network.rs:4:5
|
4 | mod server;
| ^^^^^^
|
note: maybe move this module `src/network.rs` to its own directory via `src/network/mod.rs`
--> src/network.rs:4:5
|
4 | mod server;
| ^^^^^^
note: ... or maybe `use` the module `server` instead of possibly redeclaring it
--> src/network.rs:4:5
|
4 | mod server;
| ^^^^^^
```
<span class="caption">Listing 7-5: Error when trying to extract the `server`
submodule into *src/server.rs*</span>
The error says we `cannot declare a new module at this location` and is
pointing to the `mod server;` line in *src/network.rs*. So *src/network.rs* is
different than *src/lib.rs* somehow: keep reading to understand why.
The note in the middle of Listing 7-5 is actually very helpful because it
points out something we havent yet talked about doing:
```text
note: maybe move this module `network` to its own directory via
`network/mod.rs`
```
Instead of continuing to follow the same file-naming pattern we used
previously, we can do what the note suggests:
1. Make a new *directory* named *network*, the parent modules name.
2. Move the *src/network.rs* file into the new *network* directory and
rename it *src/network/mod.rs*.
3. Move the submodule file *src/server.rs* into the *network* directory.
Here are commands to carry out these steps:
```text
$ mkdir src/network
$ mv src/network.rs src/network/mod.rs
$ mv src/server.rs src/network
```
Now when we try to run `cargo build`, compilation will work (well still have
warnings though). Our module layout still looks exactly the same as it did when
we had all the code in *src/lib.rs* in Listing 7-3:
```text
communicator
├── client
└── network
└── server
```
The corresponding file layout now looks like this:
```text
└── src
├── client.rs
├── lib.rs
└── network
├── mod.rs
└── server.rs
```
So when we wanted to extract the `network::server` module, why did we have to
also change the *src/network.rs* file to the *src/network/mod.rs* file and put
the code for `network::server` in the *network* directory in
*src/network/server.rs*? Why couldnt we just extract the `network::server`
module into *src/server.rs*? The reason is that Rust wouldnt be able to
recognize that `server` was supposed to be a submodule of `network` if the
*server.rs* file was in the *src* directory. To clarify Rusts behavior here,
lets consider a different example with the following module hierarchy, where
all the definitions are in *src/lib.rs*:
```text
communicator
├── client
└── network
└── client
```
In this example, we have three modules again: `client`, `network`, and
`network::client`. Following the same steps we did earlier for extracting
modules into files, we would create *src/client.rs* for the `client` module.
For the `network` module, we would create *src/network.rs*. But we wouldnt be
able to extract the `network::client` module into a *src/client.rs* file
because that already exists for the top-level `client` module! If we could put
the code for *both* the `client` and `network::client` modules in the
*src/client.rs* file, Rust wouldnt have any way to know whether the code was
for `client` or for `network::client`.
Therefore, in order to extract a file for the `network::client` submodule of
the `network` module, we needed to create a directory for the `network` module
instead of a *src/network.rs* file. The code that is in the `network` module
then goes into the *src/network/mod.rs* file, and the submodule
`network::client` can have its own *src/network/client.rs* file. Now the
top-level *src/client.rs* is unambiguously the code that belongs to the
`client` module.
### Rules of Module Filesystems
Lets summarize the rules of modules with regard to files:
* If a module named `foo` has no submodules, you should put the declarations
for `foo` in a file named *foo.rs*.
* If a module named `foo` does have submodules, you should put the declarations
for `foo` in a file named *foo/mod.rs*.
These rules apply recursively, so if a module named `foo` has a submodule named
`bar` and `bar` does not have submodules, you should have the following files
in your *src* directory:
```text
└── foo
├── bar.rs (contains the declarations in `foo::bar`)
└── mod.rs (contains the declarations in `foo`, including `mod bar`)
```
The modules should be declared in their parent modules file using the `mod`
keyword.
Next, well talk about the `pub` keyword and get rid of those warnings!

View File

@ -0,0 +1,46 @@
# Packages and crates for making libraries and executables
Let's talk about *packages* and *crates*. Here's a summary:
* A "crate" is a binary or library.
* The "crate root" is a source file that is used to build a crate.
* A "package" has a Cargo.toml that describes how to build one or more crates.
At most one crate can be a library.
So when we type `cargo new`, we're creating a package:
```console
> cargo new foo
> ls foo
src
.gitignore
Cargo.toml
> ls foo/src
main.rs
```
There's a `Cargo.toml`, that checks out. And while there's no *description*
of `main.rs` inside of it, by convention, if you have a `src/main.rs` in the
same directory as a package's `Cargo.toml`, Cargo understands that to be a
*binary* crate with the same name as the package. Likewise, with `src/lib.rs`,
Cargo knows that's a *library* crate with the same name as the package.
What exactly is a crate in this case? Well, we call the `main.rs` or `lib.rs`
file the "crate root", that is, the source file that corresponds to the
crate. This file is passed by Cargo to `rustc` in order to actually build
the library or binary.
A package can have:
* Zero or one library crates
* As many binary crates as it would like
* There must be at least one crate
If we have both `src/main.rs` and `src/lib.rs`, then our package has two
crates: a library and a binary, both with the same name. If we only had one
of the two, we'd have either a single library or binary. But what about more
than one binary? We'll talk about that more in Chapter 14, "More about Cargo
and Crates.io."
That's all we'll say about packages until then. And to learn more about crates,
we need to understand "modules." Read on to find out more!

View File

@ -1,288 +0,0 @@
## Controlling Visibility with `pub`
We resolved the error messages shown in Listing 7-5 by moving the `network` and
`network::server` code into the *src/network/mod.rs* and
*src/network/server.rs* files, respectively. At that point, `cargo build` was
able to build our project, but we still get warning messages about the
`client::connect`, `network::connect`, and `network::server::connect` functions
not being used.
So why are we receiving these warnings? After all, were building a library
with functions that are intended to be used by our *users*, not necessarily by
us within our own project, so it shouldnt matter that these `connect`
functions go unused. The point of creating them is that they will be used by
another project, not our own.
To understand why this program invokes these warnings, lets try using the
`communicator` library from another project, calling it externally. To do that,
well create a binary crate in the same directory as our library crate by
making a *src/main.rs* file containing this code:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
extern crate communicator;
fn main() {
communicator::client::connect();
}
```
We use the `extern crate` command to bring the `communicator` library crate
into scope. Our package now contains *two* crates. Cargo treats *src/main.rs*
as the root file of a binary crate, which is separate from the existing library
crate whose root file is *src/lib.rs*. This pattern is quite common for
executable projects: most functionality is in a library crate, and the binary
crate uses that library crate. As a result, other programs can also use the
library crate, and its a nice separation of concerns.
From the point of view of a crate outside the `communicator` library looking
in, all the modules weve been creating are within a module that has the same
name as the crate, `communicator`. We call the top-level module of a crate the
*root module*.
Also note that even if were using an external crate within a submodule of our
project, the `extern crate` should go in our root module (so in *src/main.rs*
or *src/lib.rs*). Then, in our submodules, we can refer to items from external
crates as if the items are top-level modules.
Right now, our binary crate just calls our librarys `connect` function from
the `client` module. However, invoking `cargo build` will now give us an error
after the warnings:
```text
error[E0603]: module `client` is private
--> src/main.rs:4:5
|
4 | communicator::client::connect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Ah ha! This error tells us that the `client` module is private, which is the
crux of the warnings. Its also the first time weve run into the concepts of
*public* and *private* in the context of Rust. The default state of all code in
Rust is private: no one else is allowed to use the code. If you dont use a
private function within your program, because your program is the only code
allowed to use that function, Rust will warn you that the function has gone
unused.
After you specify that a function such as `client::connect` is public, not only
will your call to that function from your binary crate be allowed, but also the
warning that the function is unused will go away. Marking a function as public
lets Rust know that the function will be used by code outside of your program.
Rust considers the theoretical external usage thats now possible as the
function “being used.” Thus, when a function is marked public, Rust will not
require that it be used in your program and will stop warning that the function
is unused.
### Making a Function Public
To tell Rust to make a function public, we add the `pub` keyword to the start
of the declaration. Well focus on fixing the warning that indicates
`client::connect` has gone unused for now, as well as the `` module `client` is
private `` error from our binary crate. Modify *src/lib.rs* to make the
`client` module public, like so:
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
pub mod client;
mod network;
```
The `pub` keyword is placed right before `mod`. Lets try building again:
```text
error[E0603]: function `connect` is private
--> src/main.rs:4:5
|
4 | communicator::client::connect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Hooray! We have a different error! Yes, different error messages are a cause
for celebration. The new error shows `` function `connect` is private ``, so
lets edit *src/client.rs* to make `client::connect` public too:
<span class="filename">Filename: src/client.rs</span>
```rust
pub fn connect() {
}
```
Now run `cargo build` again:
```text
warning: function is never used: `connect`
--> src/network/mod.rs:1:1
|
1 | / fn connect() {
2 | | }
| |_^
|
= note: #[warn(dead_code)] on by default
warning: function is never used: `connect`
--> src/network/server.rs:1:1
|
1 | / fn connect() {
2 | | }
| |_^
```
The code compiled, and the warning that `client::connect` is not being used is
gone!
Unused code warnings dont always indicate that an item in your code needs to
be made public: if you *didnt* want these functions to be part of your public
API, unused code warnings could be alerting you to code you no longer need that
you can safely delete. They could also be alerting you to a bug if you had just
accidentally removed all places within your library where this function is
called.
But in this case, we *do* want the other two functions to be part of our
crates public API, so lets mark them as `pub` as well to get rid of the
remaining warnings. Modify *src/network/mod.rs* to look like the following:
<span class="filename">Filename: src/network/mod.rs</span>
```rust,ignore
pub fn connect() {
}
mod server;
```
Then compile the code:
```text
warning: function is never used: `connect`
--> src/network/mod.rs:1:1
|
1 | / pub fn connect() {
2 | | }
| |_^
|
= note: #[warn(dead_code)] on by default
warning: function is never used: `connect`
--> src/network/server.rs:1:1
|
1 | / fn connect() {
2 | | }
| |_^
```
Hmmm, were still getting an unused function warning, even though
`network::connect` is set to `pub`. The reason is that the function is public
within the module, but the `network` module that the function resides in is not
public. Were working from the interior of the library out this time, whereas
with `client::connect` we worked from the outside in. We need to change
*src/lib.rs* to make `network` public too, like so:
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
pub mod client;
pub mod network;
```
Now when we compile, that warning is gone:
```text
warning: function is never used: `connect`
--> src/network/server.rs:1:1
|
1 | / fn connect() {
2 | | }
| |_^
|
= note: #[warn(dead_code)] on by default
```
Only one warning is left—try to fix this one on your own!
### Privacy Rules
Overall, these are the rules for item visibility:
- If an item is public, it can be accessed through any of its parent modules.
- If an item is private, it can be accessed only by its immediate parent
module and any of the parents child modules.
### Privacy Examples
Lets look at a few more privacy examples to get some practice. Create a new
library project and enter the code in Listing 7-6 into your new projects
*src/lib.rs*:
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
mod outermost {
pub fn middle_function() {}
fn middle_secret_function() {}
mod inside {
pub fn inner_function() {}
fn secret_function() {}
}
}
fn try_me() {
outermost::middle_function();
outermost::middle_secret_function();
outermost::inside::inner_function();
outermost::inside::secret_function();
}
```
<span class="caption">Listing 7-6: Examples of private and public functions,
some of which are incorrect</span>
Before you try to compile this code, make a guess about which lines in the
`try_me` function will have errors. Then, try compiling the code to see whether
you were right—and read on for the discussion of the errors!
#### Looking at the Errors
The `try_me` function is in the root module of our project. The module named
`outermost` is private, but the second privacy rule states that the `try_me`
function is allowed to access the `outermost` module because `outermost` is in
the current (root) module, as is `try_me`.
The call to `outermost::middle_function` will work because `middle_function` is
public and `try_me` is accessing `middle_function` through its parent module
`outermost`. We determined in the previous paragraph that this module is
accessible.
The call to `outermost::middle_secret_function` will cause a compilation error.
Because `middle_secret_function` is private, the second rule applies. The root
module is neither the current module of `middle_secret_function` (`outermost`
is), nor is it a child module of the current module of `middle_secret_function`.
The module named `inside` is private and has no child modules, so it can be
accessed only by its current module `outermost`. That means the `try_me`
function is not allowed to call `outermost::inside::inner_function` or
`outermost::inside::secret_function`.
#### Fixing the Errors
Here are some suggestions for changing the code in an attempt to fix the
errors. Make a guess as to whether it will fix the errors before you try each
one. Then compile the code to see whether or not youre right, using the
privacy rules to understand why. Feel free to design more experiments and try
them out!
* What if the `inside` module were public?
* What if `outermost` were public and `inside` were private?
* What if, in the body of `inner_function`, you called
`::outermost::middle_secret_function()`? (The two colons at the beginning mean
that we want to refer to the modules starting from the root module.)
Next, lets talk about bringing items into scope with the `use` keyword.

View File

@ -0,0 +1,579 @@
# Modules and use to control scope and privacy
Rust has a feature that's often referred to as "the module system," but
it encompasses a few more features than only modules. In this section,
we'll talk about:
* Modules, a way to control the privacy of paths
* Paths, a way to name things
* `use` a keyword to bring a path into scope
* `pub`, a keyword to make things public
* re-naming imports with `as`
* Using external packages
* Nested imports to clean up large import lists
* "glob imports" with `*` to bring everything into scope
* Splitting modules up into individual files
First up, modules. Here's an example of some code that uses modules:
```rust
mod foo {
fn bar() {
// code goes here
}
}
fn main() {
}
```
As you can see, we've defined two functions, `main` and `bar`. The `bar`
function, however, is inside of a `mod` block. This block defines a module
named `foo`. You can nest modules inside of other modules:
```rust
mod branch1 {
mod branch2 {
mod branch4 {
fn leaf() {
// code goes here
}
}
}
mod branch3 {
}
}
fn main() {
}
```
Remember in the last section, when we said that `main.rs` and `lib.rs` are
considered "crate roots?" This is because the contents of either of these two
files form a module named `crate`, at the root of the crate tree. So in this
example, we have a module tree that looks like this:
```text
crate
└── branch1
└── branch2
└── branch4
└── branch3
```
This might remind you of the filesystem you have on your computer; this is
a very apt comparison! The module system is similar to a filesystem in many
ways; analogies to filesystems are usually very helpful, and we'll be making
them in this chapter.
Just like directories on a filesystem, you place code inside whichever module
you'd like. How should you split up your code into modules? What should you
name those modules? In order to talk about that, we need to learn about
`pub`. But before we get to `pub`, let's talk about a seemingly simple
question: how can we call the `leaf` function?
## Paths for referring to something
If we want to call a function, we need to know its *path*. It's sort of
a synonym for "name," but evokes that filesystem metaphor. Additionally,
functions, structs, etc may have multiple paths that refer to the same
place, so "name" feels slightly off.
A *path* can take two forms:
* An *absolute path* starts with a crate name, or a literal `crate`, to refer
to the crate it's in.
* A *relative path* starts with `self`, `super`, or an identifier in the
current module.
* Both kinds of paths are followed by one or more identifiers, separated by
double colons (`::`).
What's the path of `leaf`? Let's simplify our code a bit:
```rust
mod branch1 {
mod branch2 {
fn leaf() {
// code goes here
}
}
}
fn main() {
// how do we call leaf?
}
```
If we wanted to call `leaf` from `main`, we can do it two ways:
```rust,ignore,does_not_compile
fn main() {
// absolute path
crate::branch1::branch2::leaf();
// relative path
branch1::branch2::leaf();
}
```
The former is an absolute path. Because `leaf` is defined in our crate,
we use the `crate` keyword to start an absolute path, and then include
each of the modules until we make our way to leaf. This is kind of like
running `/branch1/branch2/leaf` as a program on your computer; the `crate`
name is like starting the path with `/` in your shell.
The second one is a relative path; it starts with the name of `branch1`,
a module that's at the same level of the module tree that we are. This is
kind of like running `branch1/branch2/leaf` as a program on your computer;
starting with a name means that the path is relative.
You may be thinking "wow, that's a long name. Look at how we had to repeat
all of that `branch1::branch2` stuff just to call `leaf` twice." You're
not wrong. But before we can talk about how to simplify this example,
we have a problem: this example does not compile!
```console
> cargo build
Compiling sampleproject v0.1.0 (file:///projects/sampleproject)
error[E0603]: module `branch2` is private
--> src\main.rs:10:5
|
10 | crate::branch1::branch2::leaf();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0603]: module `branch2` is private
--> src\main.rs:12:5
|
12 | branch1::branch2::leaf();
| ^^^^^^^^^^^^^^^^^^^^^^
```
While we have the correct path for `leaf`, we cannot call it, as it's private.
It's time to learn about `pub`!
## `pub` to make paths public
Earlier, we talked about the syntax of modules, but we didn't really talk about
*why* they exist. Modules are the *privacy boundary* in Rust. In other words,
if you want to make something private, you put it in a module. Here's the
privacy rules:
* Everything is private by default.
* You can use the `pub` keyword to make something public.
* You are not allowed to use private code inside of children modules.
* You are allowed to use any code inside of parent modules or the current module.
In other words, privacy works "down" the module tree, but is public "up" the tree.
Again, think of a filesystem: if a directory is private, you cannot look into it,
but you can look inside the current directory or any parent directories.
Our error said that `branch2` was private. Let's fix that:
```rust,ignore,does_not_compile
mod branch1 {
pub mod branch2 {
fn leaf() {
// code goes here
}
}
}
fn main() {
// absolute path
crate::branch1::branch2::leaf();
// relative path
branch1::branch2::leaf();
}
```
Adding the `pub` keyword in front of `mod branch2` makes the module public.
This means that, if we're allowed to access `branch1`, we can access
`branch2`. The contents of `branch2` are still private; that is, making the
module public does not make its contents public. It purely lets code in its
parent refer to it.
We still have an error, though:
```console
> cargo build
Compiling sampleproject v0.1.0 (file:///projects/sampleproject)
error[E0603]: function `leaf` is private
--> src\main.rs:10:5
|
10 | crate::branch1::branch2::leaf();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0603]: function `leaf` is private
--> src\main.rs:12:5
|
12 | branch1::branch2::leaf();
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
```
You can use `pub` on more than only modules; you can use it on structs,
enums, and functions as well.
Let's make `leaf` public as well:
```rust,ignore
mod branch1 {
pub mod branch2 {
pub fn leaf() {
// code goes here
}
}
}
fn main() {
// absolute path
crate::branch1::branch2::leaf();
// relative path
branch1::branch2::leaf();
}
```
This will now compile! Let's look at both paths and double check why this
works.
In the absolute path case, we start with `crate`, the root of our crate. From
there, we have `branch1`, and it is a module that exists. It's not public,
but because we're in the same module as it's defined, we're allowed to refer
to it. Next is `branch2`, which is `pub`, so that's fine. Finally, `leaf`,
which is also `pub`, so we're good!
In the relative path case, it's the exact same, without the first step.
`branch1` is in the same module as us, so we're fine. `branch2` and `leaf`
are `pub`. Everything checks out!
You can also construct relative paths using `super`. This is like `..` in a
filesytem; that is, it says to start looking in the *parent* module, rather
than the current module.
```rust,ignore
mod foo {
fn bar() {
super::baz();
}
}
fn baz() {
// code goes here
}
```
`bar` is in the `foo` module, so we can use `super` to go to its parent
module, which in this case is `crate`, the root. From there, we look for
`baz`, and find it. Success!
If you use `pub` on a struct, you can make the struct public, and also its
members on a case-by-case basis:
```rust
// this struct is public...
pub struct Point {
// ... and so is x ...
pub x: i32,
// ... but y is private
y: i32,
}
```
If you make a public enum, all of its variants are public, so you only need
the `pub` next to `enum`:
```rust
pub enum ThisOrThat {
This,
That,
}
```
There's one more way to use `pub` that we haven't covered, and that's using it
along with our last module system feature: `use`.
## `use` to bring paths into scope
If we look at our code, even though we only call `leaf` twice, there's a lot of
duplication by specifying the whole path every time:
```rust,ignore
mod branch1 {
pub mod branch2 {
pub fn leaf() {
// code goes here
}
}
}
fn main() {
// here
crate::branch1::branch2::leaf();
// and here
branch1::branch2::leaf();
}
```
We can use the `use` keyword to fix this:
```rust,ignore
mod branch1 {
pub mod branch2 {
pub fn leaf() {
// code goes here
}
}
}
use crate::branch1::branch2;
fn main() {
// we can now do this!
branch2::leaf();
// this still works too
branch1::branch2::leaf();
}
```
If we say `use` and then a path, it's like creating a symlink in the
filesystem. `branch2` is now a valid name in this module, just like any
other. We can now reach it through the older, full paths, or this new path
that we've created with `use`. `use` also checks privacy, like any other
path.
If you want to use `use` with a relative path, there's a small wart: instead
of being able to use a name in the current scope, you must prefix it with
`self`:
```rust,ignore
use self::branch1::branch2;
```
This may not be neccesary in the future, but it's something to keep in mind
currently. Your authors rarely use `self`, preferring to always use `crate`
and absolute paths. This way, when you move code around, the imports it needs
don't change. Up to you!
A brief note about idioms:
```rust,ignore
// idiomatic import
use crate::branch1::branch2;
// idiomatic call
branch2::leaf();
// unidiomatic import
use crate::branch1::branch2::leaf;
// unidiomatic call
leaf();
```
For functions, it's considered idiomatic to `use` the parent module, and
use it to call the function that way. This makes it clear that it's not
locally defined, while still minimizing boilerplate.
For structs, enums, and other things, importing them directly is idiomatic
For example:
```rust,ignore
// idiomatic
use std::collections::HashMap;
let map = HashMap::new();
// not idiomatic
use std::collections;
let map = collections::HashMap::new();
```
The exception is if the names would clash:
```rust,ignore
use std::fmt;
use std::io;
fn foo() -> fmt::Result<()> {
fn foo() -> io::Result<()> {
```
We couldn't bring both `Result`s into the same scope, or their names would
clash.
## Making an import public with `pub use`
When you `use` something, it brings that name into scope, but it's private.
If you want it to be public, you can combine `pub` and `use`:
```rust,ignore
mod branch1 {
use self::branch2::leaf;
mod branch2 {
pub fn leaf() {
// code goes here
}
}
}
// this won't work
use branch1::leaf;
```
Here, while we can access `branch1` because it's in the same module, and
`leaf` does exist inside of `branch1` thanks to `use`, it's private.
If we change it to `pub use self::branch2::leaf`, it would now be public
and that line works!
`pub use` is sometimes nicknamed a "re-export", since you're both bringing
something into scope, but also making it available for others to bring into
their scope.
## Re-naming imports with `as`
Speaking of clashing names, we *could* solve this another way:
```rust,ignore
use std::fmt::Result as FmtResult;
use std::io::Result as IoResult;
fn foo() -> FmtResult<()> {
fn foo() -> IoResult<()> {
```
In other words, `as` lets us pick a differnet final name for this path. It
will still refer to the original definition, but under a different name.
Sometimes this can be a good way to avoid conflicts.
## Using external packages
If you read Chapter 2, you programmed a guessing game. That project used an
external package, `rand`, to get random numbers. To use `rand` in your own
project, you add this to your `Cargo.toml`:
```toml
[dependencies]
rand = "0.5.5"
```
And now, you can use `use` with the name of the crate, `rand`, to bring stuff into
scope:
```rust,ignore
use rand::Rng;
// Rng can now be used.
```
It's that easy!
Note that the standard library is a crate, and that means it's external to your crate.
You don't need to change `Cargo.toml` to include `std`, but you can refer to it in
`use`:
```rust
use std::collections::HashMap;
```
This is an absolute path, starting with the name of the crate: `std`.
## Nested imports for cleaning up large import lists
The guessing game project also had multiple imports with a common
prefix, like this:
```rust
use std::io;
use std::cmp::Ordering;
```
We can use 'nested paths' to make this a bit shorter:
```rust
use std::{
io,
cmp::Ordering,
};
```
Additionally, if we want to say, de-duplicate this:
```rust
use std::io;
use std::io::Write;
```
We can use `self` in the nested path:
```rust
use std::io::{self, Write};
```
This brings both `std::io` and `std::io::Write` into scope.
## Glob imports with `*`
If you'd like to bring *all* public items into scope, you can use a glob
import:
```rust
use std::collections::*;
```
Be careful with this! This makes it a little harder to tell what names are in
scope.
Glob imports are often used when testing; we'll talk about that in Chapter
11. They're also sometimes used as part of the "prelude pattern", see [the
standard library documentation](../../std/prelude/index.html#other-preludes)
for more.
## Putting modules in different files
Finally, you don't have to write all of your modules in the same file!
Instead of writing this:
```rust
mod branch1 {
fn leaf() {
// code goes here
}
}
```
You can create a new file, `src/branch1.rs`, with this in it:
```rust
fn leaf() {
// code goes here
}
```
And then modify your `lib.rs` or `main.rs` like this:
```rust,ignore
mod branch1;
```
Using a `;` instead of a block tells Rust to load the contents of the module
from another file. If we wanted to continue with our example, and put a
sub-module inside of `src/branch1.rs`:
```rust,ignore
mod branch2;
```
We would need to create a sub-folder, and a file inside of it. They would be
named `src/branch1/branch2.rs`. If `branch2` has any `mod` declarations inside
of it, you'd keep going, making sub-folders as appropriate.

View File

@ -1,304 +0,0 @@
## Referring to Names in Different Modules
Weve covered how to call functions defined within a module using the module
name as part of the call, as in the call to the `nested_modules` function shown
here in Listing 7-7:
<span class="filename">Filename: src/main.rs</span>
```rust
pub mod a {
pub mod series {
pub mod of {
pub fn nested_modules() {}
}
}
}
fn main() {
a::series::of::nested_modules();
}
```
<span class="caption">Listing 7-7: Calling a function by fully specifying its
enclosing modules path</span>
As you can see, referring to the fully qualified name can get quite lengthy.
Fortunately, Rust has a keyword to make these calls more concise.
### Bringing Names into Scope with the `use` Keyword
Rusts `use` keyword shortens lengthy function calls by bringing the modules of
the function you want to call into scope. Heres an example of bringing the
`a::series::of` module into a binary crates root scope:
<span class="filename">Filename: src/main.rs</span>
```rust
pub mod a {
pub mod series {
pub mod of {
pub fn nested_modules() {}
}
}
}
use a::series::of;
fn main() {
of::nested_modules();
}
```
The line `use a::series::of;` means that rather than using the full
`a::series::of` path wherever we want to refer to the `of` module, we can use
`of`.
The `use` keyword brings only what weve specified into scope: it does not
bring children of modules into scope. Thats why we still have to use
`of::nested_modules` when we want to call the `nested_modules` function.
We could have chosen to bring the function into scope by instead specifying the
function in the `use` as follows:
```rust
pub mod a {
pub mod series {
pub mod of {
pub fn nested_modules() {}
}
}
}
use a::series::of::nested_modules;
fn main() {
nested_modules();
}
```
Doing so allows us to exclude all the modules and reference the function
directly.
Because enums also form a sort of namespace like modules, we can bring an
enums variants into scope with `use` as well. For any kind of `use` statement,
if youre bringing multiple items from one namespace into scope, you can list
them using curly brackets and commas in the last position, like so:
```rust
enum TrafficLight {
Red,
Yellow,
Green,
}
use TrafficLight::{Red, Yellow};
fn main() {
let red = Red;
let yellow = Yellow;
let green = TrafficLight::Green;
}
```
Were still specifying the `TrafficLight` namespace for the `Green` variant
because we didnt include `Green` in the `use` statement.
#### Nested groups in `use` declarations
If you have a complex module tree with many different submodules and you need
to import a few items from each one, it might be useful to group all the
imports in the same declaration to keep your code clean and avoid repeating the
base modules name.
The `use` declaration supports nesting to help you in those cases, both with
simple imports and glob ones. For example this snippets imports `bar`, `Foo`,
all the items in `baz` and `Bar`:
```rust
# #![allow(unused_imports, dead_code)]
#
# mod foo {
# pub mod bar {
# pub type Foo = ();
# }
# pub mod baz {
# pub mod quux {
# pub type Bar = ();
# }
# }
# }
#
use foo::{
bar::{self, Foo},
baz::{*, quux::Bar},
};
#
# fn main() {}
```
### Bringing All Names into Scope with a Glob
To bring all the items in a namespace into scope at once, we can use the `*`
syntax, which is called the *glob operator*. This example brings all the
variants of an enum into scope without having to list each specifically:
```rust
enum TrafficLight {
Red,
Yellow,
Green,
}
use TrafficLight::*;
fn main() {
let red = Red;
let yellow = Yellow;
let green = Green;
}
```
The `*` will bring into scope all the visible items in the `TrafficLight`
namespace. You should use globs sparingly: they are convenient, but a glob
might also pull in more items than you expected and cause naming conflicts.
### Using `super` to Access a Parent Module
As you saw at the beginning of this chapter, when you create a library crate,
Cargo makes a `tests` module for you. Lets go into more detail about that now.
In your `communicator` project, open *src/lib.rs*:
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
pub mod client;
pub mod network;
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
```
Chapter 11 explains more about testing, but parts of this example should make
sense now: we have a module named `tests` that lives next to our other modules
and contains one function named `it_works`. Even though there are special
annotations, the `tests` module is just another module! So our module hierarchy
looks like this:
```text
communicator
├── client
├── network
| └── client
└── tests
```
Tests are for exercising the code within our library, so lets try to call our
`client::connect` function from this `it_works` function, even though we wont
be checking any functionality right now. This wont work yet:
<span class="filename">Filename: src/lib.rs</span>
```rust
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
client::connect();
}
}
```
Run the tests by invoking the `cargo test` command:
```text
$ cargo test
Compiling communicator v0.1.0 (file:///projects/communicator)
error[E0433]: failed to resolve. Use of undeclared type or module `client`
--> src/lib.rs:9:9
|
9 | client::connect();
| ^^^^^^ Use of undeclared type or module `client`
```
The compilation failed, but why? We dont need to place `communicator::` in
front of the function, as we did in *src/main.rs*, because we are definitely
within the `communicator` library crate here. The reason is that paths are
always relative to the current module, which here is `tests`. The only
exception is in a `use` statement, where paths are relative to the crate root
by default. Our `tests` module needs the `client` module in its scope!
So how do we get back up one module in the module hierarchy to call the
`client::connect` function in the `tests` module? In the `tests` module, we can
either use leading colons to let Rust know that we want to start from the root
and list the whole path, like this:
```rust,ignore
::client::connect();
```
Or, we can use `super` to move up one module in the hierarchy from our current
module, like this:
```rust,ignore
super::client::connect();
```
These two options dont look that different in this example, but if youre
deeper in a module hierarchy, starting from the root every time would make your
code lengthy. In those cases, using `super` to get from the current module to
sibling modules is a good shortcut. Plus, if youve specified the path from the
root in many places in your code and then rearrange your modules by moving a
subtree to another place, youll end up needing to update the path in several
places, which would be tedious.
It would also be annoying to have to type `super::` in each test, but youve
already seen the tool for that solution: `use`! The `super::` functionality
changes the path you give to `use` so it is relative to the parent module
instead of to the root module.
For these reasons, in the `tests` module especially, `use super::something` is
usually the best solution. So now our test looks like this:
<span class="filename">Filename: src/lib.rs</span>
```rust
#[cfg(test)]
mod tests {
use super::client;
#[test]
fn it_works() {
client::connect();
}
}
```
When we run `cargo test` again, the test will pass, and the first part of the
test result output will be the following:
```text
$ cargo test
Compiling communicator v0.1.0 (file:///projects/communicator)
Running target/debug/communicator-92007ddb5330fa5a
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
```
## Summary
Now you know some new techniques for organizing your code! Use these techniques
to group related functionality together, keep files from becoming too long, and
present a tidy public API to your library users.
Next, well look at some collection data structures in the standard library
that you can use in your nice, neat code.

View File

@ -136,7 +136,7 @@ element for. As an example, lets see what a program will do if it has a vecto
that holds five elements and then tries to access an element at index 100, as
shown in Listing 8-7:
```rust,should_panic
```rust,should_panic,panics
let v = vec![1, 2, 3, 4, 5];
let does_not_exist = &v[100];
@ -169,12 +169,14 @@ scope. That rule applies in Listing 8-8, where we hold an immutable reference to
the first element in a vector and try to add an element to the end, which wont
work:
```rust,ignore
```rust,ignore,does_not_compile
let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0];
v.push(6);
println!("The first element is: {}", first);
```
<span class="caption">Listing 8-8: Attempting to add an element to a vector
@ -184,16 +186,16 @@ Compiling this code will result in this error:
```text
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
-->
|
4 | let first = &v[0];
| - immutable borrow occurs here
5 |
6 | v.push(6);
| ^ mutable borrow occurs here
7 |
8 | }
| - immutable borrow ends here
--> src/main.rs:10:5
|
8 | let first = &v[0];
| - immutable borrow occurs here
9 |
10 | v.push(6);
| ^^^^^^^^^ mutable borrow occurs here
11 |
12 | println!("The first element is: {}", first);
| ----- borrow later used here
```
The code in Listing 8-8 might look like it should work: why should a reference

View File

@ -250,7 +250,7 @@ string by referencing them by index is a valid and common operation. However,
if you try to access parts of a `String` using indexing syntax in Rust, youll
get an error. Consider the invalid code in Listing 8-19:
```rust,ignore
```rust,ignore,does_not_compile
let s1 = String::from("hello");
let h = s1[0];
```
@ -298,7 +298,7 @@ each Unicode scalar value in that string takes 2 bytes of storage. Therefore,
an index into the strings bytes will not always correlate to a valid Unicode
scalar value. To demonstrate, consider this invalid Rust code:
```rust,ignore
```rust,ignore,does_not_compile
let hello = "Здравствуйте";
let answer = &hello[0];
```

View File

@ -261,7 +261,7 @@ loop, so all of these changes are safe and allowed by the borrowing rules.
### Hashing Functions
By default, `HashMap` uses a cryptographically secure hashing function that can
By default, `HashMap` uses a "cryptographically strong"[^siphash] hashing function that can
provide resistance to Denial of Service (DoS) attacks. This is not the fastest
hashing algorithm available, but the trade-off for better security that comes
with the drop in performance is worth it. If you profile your code and find
@ -273,6 +273,8 @@ hasher from scratch; [crates.io](https://crates.io) has libraries shared by
other Rust users that provide hashers implementing many common hashing
algorithms.
[^siphash]: [https://www.131002.net/siphash/siphash.pdf](https://www.131002.net/siphash/siphash.pdf)
## Summary
Vectors, strings, and hash maps will provide a large amount of functionality

View File

@ -28,7 +28,7 @@ Lets try calling `panic!` in a simple program:
<span class="filename">Filename: src/main.rs</span>
```rust,should_panic
```rust,should_panic,panics
fn main() {
panic!("crash and burn");
}
@ -68,7 +68,7 @@ element by index in a vector:
<span class="filename">Filename: src/main.rs</span>
```rust,should_panic
```rust,should_panic,panics
fn main() {
let v = vec![1, 2, 3];

View File

@ -451,7 +451,6 @@ shorter:
```rust
use std::io;
use std::io::Read;
use std::fs;
fn read_username_from_file() -> Result<String, io::Error> {
@ -490,25 +489,37 @@ fn main() {
When we compile this code, we get the following error message:
```text
error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
--> src/main.rs:4:13
|
4 | let f = File::open("hello.txt")?;
| ------------------------
| |
| the `?` operator can only be used in a function that returns
`Result` (or another type that implements `std::ops::Try`)
| in this macro invocation
| ^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `std::ops::Try` is not implemented for `()`
= note: required by `std::ops::Try::from_error`
```
This error points out that were only allowed to use `?` in a function that
returns `Result`. In functions that dont return `Result`, when you call other
functions that return `Result`, youll need to use a `match` or one of the
`Result` methods to handle the `Result` instead of using `?` to potentially
propagate the error to the calling code.
returns `Result<T, E>`. In functions that dont return `Result<T, E>`, when
you call other functions that return `Result<T, E>`, youll need to use a
`match` or one of the `Result<T, E>` methods to handle the `Result<T, E>`
instead of using `?` to potentially propagate the error to the calling code.
However, the `main` function can return a `Result<T, E>`:
```rust,ignore
use std::error::Error;
use std::fs::File;
fn main() -> Result<(), Box<dyn Error>> {
let f = File::open("hello.txt")?;
Ok(())
}
```
The `Box<dyn Error>` is called a "trait object", which we'll talk about in Chapter 17.
For now, you can read `Box<dyn Error>` to mean "any kind of error."
Now that weve discussed the details of calling `panic!` or returning `Result`,
lets return to the topic of how to decide which is appropriate to use in which

View File

@ -163,7 +163,7 @@ tedious (and might impact performance).
Instead, we can make a new type and put the validations in a function to create
an instance of the type rather than repeating the validations everywhere. That
way, its safe for functions to use the new type in their signatures and
confidently use the values they receive. Listing 9-9 shows one way to define a
confidently use the values they receive. Listing 9-10 shows one way to define a
`Guess` type that will only create an instance of `Guess` if the `new` function
receives a value between 1 and 100:

View File

@ -94,7 +94,7 @@ compile yet, but well fix it later in this chapter.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn largest<T>(list: &[T]) -> T {
let mut largest = list[0];
@ -182,7 +182,7 @@ Listing 10-7, our code wont compile.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
struct Point<T> {
x: T,
y: T,

View File

@ -301,18 +301,29 @@ say we wanted to take two things that implement `Summary`:
```rust,ignore
pub fn notify(item1: impl Summary, item2: impl Summary) {
```
This would work well if `item1` and `item2` were allowed to have diferent types
(as long as both implement `Summary`). But what if you wanted to force both to
have the exact same type? That is only possible if you use a trait bound:
```rust,ignore
pub fn notify<T: Summary>(item1: T, item2: T) {
```
The version with the bound is a bit easier. In general, you should use whatever
form makes your code the most understandable.
#### Specify multiple traits with `+`
##### Multiple trait bounds with `+`
If `notify` needed to display formatting on `item`, as well as use the `summarize`
method, then `item` would need to implement two different traits at the same time:
`Display` and `Summary`. This can be done using the `+` syntax:
We can specify multiple trait bounds on a generic type using the `+` syntax.
For example, to use display formatting on the type `T` in a function as well as
the `summarize` method, we can use `T: Summary + Display` to say `T` can be any
type that implements `Summary` and `Display`. This can grow quite complex!
```rust,ignore
pub fn notify(item: impl Summary + Display) {
```
This syntax is also valid with trait bounds on generic types:
```rust,ignore
pub fn notify<T: Summary + Display>(item: T) {
```
#### `where` clauses for clearer code
@ -369,7 +380,7 @@ needing to write out a really long type.
This only works if you have a single type that you're returning, however.
For example, this would *not* work:
```rust,ignore
```rust,ignore,does_not_compile
fn returns_summarizable(switch: bool) -> impl Summary {
if switch {
NewsArticle {

View File

@ -23,7 +23,7 @@ program to reference data other than the data its intended to reference.
Consider the program in Listing 10-17, which has an outer scope and an inner
scope.
```rust,ignore
```rust,ignore,does_not_compile
{
let r;
@ -80,7 +80,7 @@ The Rust compiler has a *borrow checker* that compares scopes to determine
whether all borrows are valid. Listing 10-18 shows the same code as Listing
10-17 but with annotations showing the lifetimes of the variables.
```rust,ignore
```rust,ignore,does_not_compile
{
let r; // ---------+-- 'a
// |
@ -165,7 +165,7 @@ wont compile.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() {
x
@ -345,7 +345,7 @@ compile.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let string1 = String::from("long string is long");
let result;
@ -423,7 +423,7 @@ this attempted implementation of the `longest` function that wont compile:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn longest<'a>(x: &str, y: &str) -> &'a str {
let result = String::from("really long string");
result.as_str()
@ -576,6 +576,8 @@ and the second and third rules apply to output lifetimes. If the compiler gets
to the end of the three rules and there are still references for which it cant
figure out lifetimes, the compiler will stop with an error.
These rules apply to `fn` definitions, as well as `impl` blocks.
The first rule is that each parameter that is a reference gets its own lifetime
parameter. In other words, a function with one parameter gets one lifetime
parameter: `fn foo<'a>(x: &'a i32)`; a function with two parameters gets two

View File

@ -157,7 +157,7 @@ which is to call the `panic!` macro. Enter the new test, `another`, so your
<span class="filename">Filename: src/lib.rs</span>
```rust
```rust,panics
# fn main() {}
#[cfg(test)]
mod tests {
@ -340,7 +340,7 @@ introduce a bug in our code. Lets change the implementation of the `can_hold`
method by replacing the greater-than sign with a less-than sign when it
compares the lengths:
```rust
```rust,not_desired_behavior
# fn main() {}
# #[derive(Debug)]
# pub struct Rectangle {
@ -436,7 +436,7 @@ Lets introduce a bug into our code to see what it looks like when a test that
uses `assert_eq!` fails. Change the implementation of the `add_two` function to
instead add `3`:
```rust
```rust,not_desired_behavior
# fn main() {}
pub fn add_two(a: i32) -> i32 {
a + 3
@ -544,7 +544,7 @@ input parameter.
Lets introduce a bug into this code by changing `greeting` to not include
`name` to see what this test failure looks like:
```rust
```rust,not_desired_behavior
# fn main() {}
pub fn greeting(name: &str) -> String {
String::from("Hello!")
@ -602,7 +602,7 @@ debug what happened instead of what we were expecting to happen.
In addition to checking that our code returns the correct values we expect,
its also important to check that our code handles error conditions as we
expect. For example, consider the `Guess` type that we created in Chapter 9,
Listing 9-9. Other code that uses `Guess` depends on the guarantee that `Guess`
Listing 9-10. Other code that uses `Guess` depends on the guarantee that `Guess`
instances will contain only values between 1 and 100. We can write a test that
ensures that attempting to create a `Guess` instance with a value outside that
range panics.
@ -663,7 +663,7 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Looks good! Now lets introduce a bug in our code by removing the condition
that the `new` function will panic if the value is greater than 100:
```rust
```rust,not_desired_behavior
# fn main() {}
# pub struct Guess {
# value: i32,
@ -766,7 +766,7 @@ To see what happens when a `should_panic` test with an `expected` message
fails, lets again introduce a bug into our code by swapping the bodies of the
`if value < 1` and the `else if value > 100` blocks:
```rust,ignore
```rust,ignore,not_desired_behavior
if value < 1 {
panic!("Guess value must be less than or equal to 100, got {}.", value);
} else if value > 100 {

View File

@ -61,7 +61,7 @@ parameter and returns 10, as well as a test that passes and a test that fails.
<span class="filename">Filename: src/lib.rs</span>
```rust
```rust,panics
fn prints_and_returns_10(a: i32) -> i32 {
println!("I got the value {}", a);
10

View File

@ -58,7 +58,7 @@ First, we add another `use` statement to bring in a relevant part of the
standard library: we need `std::fs` to handle files.
In `main`, weve added a new statement: `fs::read_to_string` will take the
`filename`, open that file, and then produce a new `String` with its contents.
`filename`, open that file, and then return `Result<String>` with its contents.
After that line, weve again added a temporary `println!` statement that
prints the value of `contents` after the file is read, so we can check that the

View File

@ -306,7 +306,7 @@ fn new(args: &[String]) -> Config {
<span class="caption">Listing 12-8: Adding a check for the number of
arguments</span>
This code is similar to the `Guess::new` function we wrote in Listing 9-9, where
This code is similar to the `Guess::new` function we wrote in Listing 9-10, where
we called `panic!` when the `value` argument was out of the range of valid
values. Instead of checking for a range of values here, were checking that the
length of `args` is at least `3` and the rest of the function can operate under
@ -328,7 +328,7 @@ note: Run with `RUST_BACKTRACE=1` for a backtrace.
This output is better: we now have a reasonable error message. However, we also
have extraneous information we dont want to give to our users. Perhaps using
the technique we used in Listing 9-9 isnt the best to use here: a call to
the technique we used in Listing 9-10 isnt the best to use here: a call to
`panic!` is more appropriate for a programming problem rather than a usage
problem, as discussed in Chapter 9. Instead, we can use the other technique you
learned about in Chapter 9—returning a `Result` that indicates either success
@ -669,4 +669,4 @@ modular. Almost all of our work will be done in *src/lib.rs* from here on out.
Lets take advantage of this newfound modularity by doing something that would
have been difficult with the old code but is easy with the new code: well
write some tests!
write some tests!

View File

@ -384,7 +384,7 @@ first time and a `u32` the second time, well get an error.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
let example_closure = |x| x;
let s = example_closure(String::from("hello"));
@ -634,7 +634,7 @@ The first problem is that a `Cacher` instance assumes it will always get the
same value for the parameter `arg` to the `value` method. That is, this test of
`Cacher` will fail:
```rust,ignore
```rust,ignore,panics
#[test]
fn call_with_different_values() {
let mut c = Cacher::new(|a| a);
@ -714,7 +714,7 @@ code wont compile:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let x = 4;
@ -780,7 +780,7 @@ yet compile.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let x = vec![1, 2, 3];

View File

@ -168,7 +168,7 @@ incremented by 1. However, this code produces a warning:
<span class="filename">Filename: src/main.rs</span>
```rust
```rust,not_desired_behavior
let v1: Vec<i32> = vec![1, 2, 3];
v1.iter().map(|x| x + 1);

View File

@ -106,7 +106,7 @@ well demonstrate.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
enum List {
Cons(i32, List),
Nil,

View File

@ -131,7 +131,7 @@ code in Listing 15-9 wont compile because Rust doesnt know how to derefere
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let x = 5;
let y = MyBox::new(x);

View File

@ -95,7 +95,7 @@ compiler error:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let c = CustomSmartPointer { data: String::from("some data") };
println!("CustomSmartPointer created.");

View File

@ -50,7 +50,7 @@ wont work, as shown in Listing 15-17:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
enum List {
Cons(i32, Box<List>),
Nil,

View File

@ -77,7 +77,7 @@ examine how its possible.
A consequence of the borrowing rules is that when you have an immutable value,
you cant borrow it mutably. For example, this code wont compile:
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let x = 5;
let y = &mut x;
@ -195,7 +195,7 @@ implement a mock object to do just that, but the borrow checker wont allow it
<span class="filename">Filename: src/lib.rs</span>
```rust
```rust,does_not_compile
#[cfg(test)]
mod tests {
use super::*;
@ -353,7 +353,7 @@ at runtime.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,panics
impl Messenger for MockMessenger {
fn send(&self, message: &str) {
let mut one_borrow = self.sent_messages.borrow_mut();

View File

@ -254,7 +254,7 @@ thread. However, this wont yet work, as youll see in a moment.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
use std::thread;
fn main() {
@ -303,7 +303,7 @@ that wont be valid:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
use std::thread;
fn main() {

View File

@ -169,7 +169,7 @@ this code isn't allowed:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
use std::thread;
use std::sync::mpsc;

View File

@ -109,7 +109,7 @@ starting example:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
use std::sync::Mutex;
use std::thread;
@ -187,7 +187,7 @@ Lets figure this out by simplifying the program. Instead of making 10 threads
in a `for` loop, lets just make two threads without a loop and see what
happens. Replace the first `for` loop in Listing 16-13 with this code instead:
```rust,ignore
```rust,ignore,does_not_compile
use std::sync::Mutex;
use std::thread;
@ -269,7 +269,7 @@ errors, well also switch back to using the `for` loop, and well keep the
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
use std::rc::Rc;
use std::sync::Mutex;
use std::thread;

View File

@ -295,7 +295,7 @@ with a `String` as a component:
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
extern crate gui;
use gui::Screen;
@ -396,7 +396,7 @@ rules of object safety in regard to trait objects. For example, lets say we
tried to implement the `Screen` struct in Listing 17-4 to hold types that
implement the `Clone` trait instead of the `Draw` trait, like this:
```rust,ignore
```rust,ignore,does_not_compile
pub struct Screen {
pub components: Vec<Box<dyn Clone>>,
}

View File

@ -208,7 +208,7 @@ in the tuple, the overall type wont match and well get a compiler error. F
example, Listing 18-5 shows an attempt to destructure a tuple with three
elements into two variables, which wont work.
```rust,ignore
```rust,ignore,does_not_compile
let (x, y) = (1, 2, 3);
```

View File

@ -26,7 +26,7 @@ where Rust requires an irrefutable pattern and vice versa. Listing 18-8 shows a
`let` statement, but for the pattern weve specified `Some(x)`, a refutable
pattern. As you might expect, this code will not compile.
```rust,ignore
```rust,ignore,does_not_compile
let Some(x) = some_option_value;
```
@ -71,7 +71,7 @@ cannot use an irrefutable pattern without receiving an error. If we give `if
let` a pattern that will always match, such as `x`, as shown in Listing 18-10,
it will not compile.
```rust,ignore
```rust,ignore,does_not_compile
if let x = 5 {
println!("{}", x);
};

View File

@ -579,7 +579,7 @@ that starts with an underscore. The syntax `_x` still binds the value to the
variable, whereas `_` doesnt bind at all. To show a case where this
distinction matters, Listing 18-21 will provide us with an error.
```rust,ignore
```rust,ignore,does_not_compile
let s = Some(String::from("Hello!"));
if let Some(_s) = s {
@ -674,7 +674,7 @@ compile.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
let numbers = (2, 4, 8, 16, 32);

View File

@ -126,7 +126,7 @@ Recall that we can create raw pointers in safe code, but we cant *dereference
raw pointers and read the data being pointed to. In Listing 19-3, we use the
dereference operator `*` on a raw pointer that requires an `unsafe` block.
```rust
```rust,unsafe
let mut num = 5;
let r1 = &num as *const i32;
@ -174,7 +174,7 @@ responsibility for upholding the functions contracts.
Here is an unsafe function named `dangerous` that doesnt do anything in its
body:
```rust
```rust,unsafe
unsafe fn dangerous() {}
unsafe {
@ -231,7 +231,7 @@ something like Listing 19-5, which wont compile. For simplicity, well
implement `split_at_mut` as a function rather than a method and only for slices
of `i32` values rather than for a generic type `T`.
```rust,ignore
```rust,ignore,does_not_compile
fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
let len = slice.len();
@ -278,7 +278,7 @@ know code is okay, but Rust doesnt, its time to reach for unsafe code.
Listing 19-6 shows how to use an `unsafe` block, a raw pointer, and some calls
to unsafe functions to make the implementation of `split_at_mut` work.
```rust
```rust,unsafe
use std::slice;
fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
@ -332,7 +332,7 @@ In contrast, the use of `slice::from_raw_parts_mut` in Listing 19-7 would
likely crash when the slice is used. This code takes an arbitrary memory
location and creates a slice 10,000 items long.
```rust
```rust,unsafe
use std::slice;
let address = 0x01234usize;
@ -370,7 +370,7 @@ responsibility falls on the programmer to ensure safety.
<span class="filename">Filename: src/main.rs</span>
```rust
```rust,unsafe
extern "C" {
fn abs(input: i32) -> i32;
}
@ -459,7 +459,7 @@ static variable named `COUNTER`.
<span class="filename">Filename: src/main.rs</span>
```rust
```rust,unsafe
static mut COUNTER: u32 = 0;
fn add_to_count(inc: u32) {
@ -500,7 +500,7 @@ compiler cant verify. We can declare that a trait is `unsafe` by adding the
`unsafe` keyword before `trait` and marking the implementation of the trait as
`unsafe` too, as shown in Listing 19-11.
```rust
```rust,unsafe
unsafe trait Foo {
// methods go here
}

View File

@ -24,7 +24,7 @@ have the required lifetime annotations, so it wont compile.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
struct Context(&str);
struct Parser {
@ -100,7 +100,7 @@ returns. This code doesnt quite work.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn parse_context(context: Context) -> Result<(), &str> {
Parser { context: &context }.parse()
}
@ -214,7 +214,7 @@ sufficient when we try to compile.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
struct Context<'s>(&'s str);
struct Parser<'c, 's> {
@ -317,7 +317,7 @@ struct is shown in Listing 19-16, without lifetime bounds for now.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
struct Ref<'a, T>(&'a T);
```

View File

@ -429,7 +429,7 @@ Listing 19-28, well get a compilation error.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
fn main() {
println!("A baby dog is called a {}", Animal::baby_name());
}

View File

@ -201,7 +201,7 @@ At the time, we skipped over some details in this code. In Chapter 6 in “The
`match` Control Flow Operator” section, we discussed that `match` arms must all
return the same type. So, for example, the following code doesnt work:
```rust,ignore
```rust,ignore,does_not_compile
let guess = match guess.trim().parse() {
Ok(_) => 5,
Err(_) => "hello",
@ -273,7 +273,7 @@ its own, is a DST. We cant know how long the string is until runtime, meaning
we cant create a variable of type `str`, nor can we take an argument of type
`str`. Consider the following code, which does not work:
```rust,ignore
```rust,ignore,does_not_compile
let s1: str = "Hello there!";
let s2: str = "How's it going?";
```

View File

@ -83,6 +83,25 @@ named `to_string`. Here, were using the `to_string` function defined in the
`ToString` trait, which the standard library has implemented for any type that
implements `Display`.
Another useful pattern exploits an implementation detail of tuple structs and
tuple-struct enum variants. These items use `()` as initialiser syntax, which
looks like a function call, and they're actually implemented as functions
returning an instance constructed from their arguments. They can also be called
as a function pointer implementing the closure traits, and so can be used
similarly to the above:
```rust
enum Status {
Value(u32),
Stop,
}
let list_of_statuses: Vec<Status> =
(0u32..20)
.map(Status::Value)
.collect();
```
Some people prefer this style, and some people prefer to use closures. They end
up compiling to the same code, so use whichever style is clearer to you.
@ -97,7 +116,7 @@ pointer `fn` as a return type, for example.
The following code tries to return a closure directly, but it wont compile:
```rust,ignore
```rust,ignore,does_not_compile
fn returns_closure() -> Fn(i32) -> i32 {
|x| x + 1
}

View File

@ -0,0 +1,528 @@
## Macros
Weve used macros like `println!` throughout this book but havent fully
explored what a macro is and how it works. There's a lot more to them,
though; "macros" refer to a family of different features in Rust:
* *Declarative* macros with `macro_rules`
* *Procedural*, which have three sub-kinds:
* Custom `#[derive]`s
* Attribute-like macros
* Function-like macros
We'll talk about each of these in turn, but first, why do we even
need macros when we already have functions?
### The Difference Between Macros and Functions
Fundamentally, macros are a way of writing code that writes other code, which
is known as *metaprogramming*. In Appendix C, we discussed the `derive`
attribute, which generates an implementation of various traits for you. Weve
also used the `println!` and `vec!` macros throughout the book. All of these
macros *expand* to produce more code than the code youve written manually.
Metaprogramming is useful for reducing the amount of code you have to write and
maintain, which is also one of the roles of functions. However, macros have
some additional powers that functions dont have.
A function signature must declare the number and type of parameters the
function has. Macros, on the other hand, can take a variable number of
parameters: we can call `println!("hello")` with one argument or
`println!("hello {}", name)` with two arguments. Also, macros are expanded
before the compiler interprets the meaning of the code, so a macro can, for
example, implement a trait on a given type. A function cant, because it gets
called at runtime and a trait needs to be implemented at compile time.
The downside to implementing a macro instead of a function is that macro
definitions are more complex than function definitions because youre writing
Rust code that writes Rust code. Due to this indirection, macro definitions are
generally more difficult to read, understand, and maintain than function
definitions.
There is one last important difference between macros and functions: you must
define or bring macros into scope *before* you call them in a file, whereas you
can define functions anywhere and call them anywhere.
### Declarative Macros with `macro_rules!` for General Metaprogramming
The most widely used form of macros in Rust are *declarative macros*. These are
also sometimes referred to as *macros by example*, *`macro_rules!` macros*, or
just plain *macros*. At their core, declarative macros allow you to write
something similar to a Rust `match` expression. As discussed in Chapter 6,
`match` expressions are control structures that take an expression, compare the
resulting value of the expression to patterns, and then run the code associated
with the matching pattern. Macros also compare a value to patterns that have
code associated with them; in this situation, the value is the literal Rust
source code passed to the macro, the patterns are compared with the structure
of that source code, and the code associated with each pattern is the code that
replaces the code passed to the macro. This all happens during compilation.
To define a macro, you use the `macro_rules!` construct. Lets explore how to
use `macro_rules!` by looking at how the `vec!` macro is defined. Chapter 8
covered how we can use the `vec!` macro to create a new vector with particular
values. For example, the following macro creates a new vector with three
integers inside:
```rust
let v: Vec<u32> = vec![1, 2, 3];
```
We could also use the `vec!` macro to make a vector of two integers or a vector
of five string slices. We wouldnt be able to use a function to do the same
because we wouldnt know the number or type of values up front.
Lets look at a slightly simplified definition of the `vec!` macro in Listing
D-1.
```rust
#[macro_export]
macro_rules! vec {
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(
temp_vec.push($x);
)*
temp_vec
}
};
}
```
<span class="caption">Listing D-1: A simplified version of the `vec!` macro
definition</span>
> Note: The actual definition of the `vec!` macro in the standard library
> includes code to preallocate the correct amount of memory up front. That code
> is an optimization that we dont include here to make the example simpler.
The `#[macro_export]` annotation indicates that this macro should be made
available whenever the crate in which were defining the macro is imported.
Without this annotation, the macro can't be brought into scope.
We then start the macro definition with `macro_rules!` and the name of the
macro were defining *without* the exclamation mark. The name, in this case
`vec`, is followed by curly brackets denoting the body of the macro definition.
The structure in the `vec!` body is similar to the structure of a `match`
expression. Here we have one arm with the pattern `( $( $x:expr ),* )`,
followed by `=>` and the block of code associated with this pattern. If the
pattern matches, the associated block of code will be emitted. Given that this
is the only pattern in this macro, there is only one valid way to match; any
other will be an error. More complex macros will have more than one arm.
Valid pattern syntax in macro definitions is different than the pattern syntax
covered in Chapter 18 because macro patterns are matched against Rust code
structure rather than values. Lets walk through what the pieces of the pattern
in Listing D-1 mean; for the full macro pattern syntax, see [the reference].
[the reference]: ../../reference/macros.html
First, a set of parentheses encompasses the whole pattern. Next comes a dollar
sign (`$`) followed by a set of parentheses, which captures values that match
the pattern within the parentheses for use in the replacement code. Within
`$()` is `$x:expr`, which matches any Rust expression and gives the expression
the name `$x`.
The comma following `$()` indicates that a literal comma separator character
could optionally appear after the code that matches the code captured in `$()`.
The `*` following the comma specifies that the pattern matches zero or more of
whatever precedes the `*`.
When we call this macro with `vec![1, 2, 3];`, the `$x` pattern matches three
times with the three expressions `1`, `2`, and `3`.
Now lets look at the pattern in the body of the code associated with this arm:
the `temp_vec.push()` code within the `$()*` part is generated for each part
that matches `$()` in the pattern, zero or more times depending on how many
times the pattern matches. The `$x` is replaced with each expression matched.
When we call this macro with `vec![1, 2, 3];`, the code generated that replaces
this macro call will be the following:
```rust,ignore
let mut temp_vec = Vec::new();
temp_vec.push(1);
temp_vec.push(2);
temp_vec.push(3);
temp_vec
```
Weve defined a macro that can take any number of arguments of any type and can
generate code to create a vector containing the specified elements.
There are some strange corners with `macro_rules!`. In the future, there
will be a second kind of declarative macro, with the `macro` keyword, that
will work in a similar fashion, but fix some of these edge cases. After that
is done, `macro_rules` will be effectively deprecated. With this
in mind, as well as the fact that most Rust programmers will *use* macros
more than *write* macros, we wont discuss `macro_rules!` any further. To
learn more about how to write macros, consult the online documentation or
other resources, such as [“The Little Book of Rust Macros”][tlborm].
[tlborm]: https://danielkeep.github.io/tlborm/book/index.html
## Procedural macros
The second form of macros is called *procedural macros* because theyre more
like functions (which are a type of procedure). Procedural macros accept some
Rust code as an input, operate on that code, and produce some Rust code as an
output rather than matching against patterns and replacing the code with other
code as declarative macros do.
While there are three kinds of procedural macros, they all work in a similar
fashion. First, they must reside in their own crate, with a special crate type.
This is for complex technical reasons that we hope to eliminate in the future,
and so won't discuss here. Second, they all take a form like this:
```rust,ignore
extern crate proc_macro;
#[some_attribute]
pub fn some_name(input: TokenStream) -> TokenStream {
}
```
First, the `extern crate` line. `extern crate` is a holdover from the old
Rust module system; for now, when defining a proc macro, you must add this
line to your `src/lib.rs`. Someday, this will not be necessary.
Second, procedural macros consist of a function, which is how they get their
name: "procedure" is a synonym for "function." Why not call them "functional
macros"? Well, one of the types is "function-like", and that would get
confusing. Anyway, the function takes a `TokenStream` as an input, and
produces a `TokenStream` as an output. This is the core of the macro;
the source that the macro is operating on makes up the input `TokenStream`,
and the code we produce from our macro is the output `TokenStream`.
We'll talk more about `TokenStream` when we actually build one of these
things. Finally, the function has an attribute on it; this attribute
says which kind of procedural macro we're creating. We can have multiple
kinds of procedual macros in the same crate.
Given that the kinds of macros are so similar, we'll start with a custom
derive macro, and then in the other sections, we'll explain the small
differences that make the other forms different.
### Custom Derive
Let's create a crate named `hello_macro` that defines a trait named
`HelloMacro` with one associated function named `hello_macro`. Rather than
making our crate users implement the `HelloMacro` trait for each of their
types, well provide a procedural macro so users can annotate their type with
`#[derive(HelloMacro)]` to get a default implementation of the `hello_macro`
function. The default implementation will print `Hello, Macro! My name is
TypeName!` where `TypeName` is the name of the type on which this trait has
been defined. In other words, well write a crate that enables another
programmer to write code like Listing D-2 using our crate.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
use hello_macro::HelloMacro;
#[derive(HelloMacro)]
struct Pancakes;
fn main() {
Pancakes::hello_macro();
}
```
<span class="caption">Listing D-2: The code a user of our crate will be able to
write when using our procedural macro</span>
This code will print `Hello, Macro! My name is Pancakes!` when were done. The
first step is to make a new library crate, like this:
```text
$ cargo new hello_macro --lib
```
Next, well define the `HelloMacro` trait and its associated function:
<span class="filename">Filename: src/lib.rs</span>
```rust
pub trait HelloMacro {
fn hello_macro();
}
```
We have a trait and its function. At this point, our crate user could implement
the trait to achieve the desired functionality, like so:
```rust,ignore
use hello_macro::HelloMacro;
struct Pancakes;
impl HelloMacro for Pancakes {
fn hello_macro() {
println!("Hello, Macro! My name is Pancakes!");
}
}
fn main() {
Pancakes::hello_macro();
}
```
However, they would need to write the implementation block for each type they
wanted to use with `hello_macro`; we want to spare them from having to do this
work.
Additionally, we cant yet provide a default implementation for the
`hello_macro` function that will print the name of the type the trait is
implemented on: Rust doesnt have reflection capabilities, so it cant look up
the types name at runtime. We need a macro to generate code at compile time.
The next step is to define the procedural macro. At the time of this writing,
procedural macros need to be in their own crate. Eventually, this restriction
might be lifted. The convention for structuring crates and macro crates is as
follows: for a crate named `foo`, a custom derive procedural macro crate is
called `foo_derive`. Lets start a new crate called `hello_macro_derive` inside
our `hello_macro` project:
```text
$ cargo new hello_macro_derive --lib
```
Our two crates are tightly related, so we create the procedural macro crate
within the directory of our `hello_macro` crate. If we change the trait
definition in `hello_macro`, well have to change the implementation of the
procedural macro in `hello_macro_derive` as well. The two crates will need to
be published separately, and programmers using these crates will need to add
both as dependencies and bring them both into scope. We could instead have the
`hello_macro` crate use `hello_macro_derive` as a dependency and reexport the
procedural macro code. But the way weve structured the project makes it
possible for programmers to use `hello_macro` even if they dont want the
`derive` functionality.
We need to declare the `hello_macro_derive` crate as a procedural macro crate.
Well also need functionality from the `syn` and `quote` crates, as youll see
in a moment, so we need to add them as dependencies. Add the following to the
*Cargo.toml* file for `hello_macro_derive`:
<span class="filename">Filename: hello_macro_derive/Cargo.toml</span>
```toml
[lib]
proc-macro = true
[dependencies]
syn = "0.14.4"
quote = "0.6.3"
```
To start defining the procedural macro, place the code in Listing D-3 into your
*src/lib.rs* file for the `hello_macro_derive` crate. Note that this code wont
compile until we add a definition for the `impl_hello_macro` function.
<span class="filename">Filename: hello_macro_derive/src/lib.rs</span>
```rust,ignore
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn;
#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
// Construct a represntation of Rust code as a syntax tree
// that we can manipulate
let ast = syn::parse(input).unwrap();
// Build the trait implementation
impl_hello_macro(&ast)
}
```
<span class="caption">Listing D-3: Code that most procedural macro crates will
need to have for processing Rust code</span>
Notice the way weve split the functions in D-3; this will be the same for
almost every procedural macro crate you see or create, because it makes writing
a procedural macro more convenient. What you choose to do in the place where
the `impl_hello_macro` function is called will be different depending on your
procedural macros purpose.
Weve introduced three new crates: `proc_macro`, [`syn`], and [`quote`]. The
`proc_macro` crate comes with Rust, so we didnt need to add that to the
dependencies in *Cargo.toml*. The `proc_macro` crate is the compiler's API to
be able to read and manipulate Rust code from our code. The `syn` crate
parses Rust code from a string into a data structure that we can perform
operations on. The `quote` crate takes `syn` data structures and turns them
back into Rust code. These crates make it much simpler to parse any sort of
Rust code we might want to handle: writing a full parser for Rust code is no
simple task.
[`syn`]: https://crates.io/crates/syn
[`quote`]: https://crates.io/crates/quote
The `hello_macro_derive` function will get called when a user of our library
specifies `#[derive(HelloMacro)]` on a type. The reason is that weve annotated
the `hello_macro_derive` function here with `proc_macro_derive` and specified
the name, `HelloMacro`, which matches our trait name; thats the convention
most procedural macros follow.
This function first converts the `input` from a `TokenStream` to a data
structure that we can then interpret and perform operations on. This is where
`syn` comes into play. The `parse` function in `syn` takes a `TokenStream` and
returns a `DeriveInput` struct representing the parsed Rust code. The following
code shows the relevant parts of the `DeriveInput` struct we get from parsing
the string `struct Pancakes;`:
```rust,ignore
DeriveInput {
// --snip--
ident: Ident(
"Pancakes"
),
body: Struct(
Unit
)
}
```
The fields of this struct show that the Rust code weve parsed is a unit struct
with the `ident` (identifier, meaning the name) of `Pancakes`. There are more
fields on this struct for describing all sorts of Rust code; check the [`syn`
documentation for `DeriveInput`][syn-docs] for more information.
[syn-docs]: https://docs.rs/syn/0.11.11/syn/struct.DeriveInput.html
At this point, we havent defined the `impl_hello_macro` function, which is
where well build the new Rust code we want to include. But before we do, note
that its output is also a `TokenStream` which is added to the code that our
crate users write, so when they compile their crate, theyll get extra
functionality that we provide.
You might have noticed that were calling `unwrap` to panic if the call to the
`syn::parse`function fails here. Panicking on errors is necessary in procedural
macro code because `proc_macro_derive` functions must return `TokenStream`
rather than `Result` to conform to the procedural macro API. Weve chosen to
simplify this example by using `unwrap`; in production code, you should provide
more specific error messages about what went wrong by using `panic!` or `expect`.
Now that we have the code to turn the annotated Rust code from a `TokenStream`
into a `DeriveInput` instance, lets generate the code that implements the
`HelloMacro` trait on the annotated type:
<span class="filename">Filename: hello_macro_derive/src/lib.rs</span>
```rust,ignore
fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let gen = quote! {
impl HelloMacro for #name {
fn hello_macro() {
println!("Hello, Macro! My name is {}", stringify!(#name));
}
}
};
gen.into()
}
```
We get an `Ident` struct instance containing the name (identifier) of the
annotated type using `ast.ident`. The code in Listing D-2 specifies that the
`name` will be `Ident("Pancakes")`.
The `quote!` macro lets us write the Rust code that we want to return, but the
direct result of its execution is not what is expected by the compiler and needs
to be converted to a `TokenStream` by calling the `into` method. `into` consumes
this intermediate representation and returns a value of the required type.
This macro also provides some very cool templating mechanics; we can write
`#name`, and `quote!` will replace it with the value in the variable named
`name`. You can even do some repetition similar
to the way regular macros work. Check out [the `quote` crates docs][quote-docs]
for a thorough introduction.
[quote-docs]: https://docs.rs/quote
We want our procedural macro to generate an implementation of our `HelloMacro`
trait for the type the user annotated, which we can get by using `#name`. The
trait implementation has one function, `hello_macro`, whose body contains the
functionality we want to provide: printing `Hello, Macro! My name is` and then
the name of the annotated type.
The `stringify!` macro used here is built into Rust. It takes a Rust
expression, such as `1 + 2`, and at compile time turns the expression into a
string literal, such as `"1 + 2"`. This is different than `format!` or
`println!`, which evaluate the expression and then turn the result into a
`String`. There is a possibility that the `#name` input might be an expression
to print literally, so we use `stringify!`. Using `stringify!` also saves an
allocation by converting `#name` to a string literal at compile time.
At this point, `cargo build` should complete successfully in both `hello_macro`
and `hello_macro_derive`. Lets hook up these crates to the code in Listing D-2
to see the procedural macro in action! Create a new binary project in your
*projects* directory using `cargo new pancakes`. We need to add
`hello_macro` and `hello_macro_derive` as dependencies in the `pancakes`
crates *Cargo.toml*. If youre publishing your versions of `hello_macro` and
`hello_macro_derive` to *https://crates.io/*, they would be regular
dependencies; if not, you can specify them as `path` dependencies as follows:
```toml
[dependencies]
hello_macro = { path = "../hello_macro" }
hello_macro_derive = { path = "../hello_macro/hello_macro_derive" }
```
Put the code from Listing D-2 into *src/main.rs*, and run `cargo run`: it
should print `Hello, Macro! My name is Pancakes!` The implementation of the
`HelloMacro` trait from the procedural macro was included without the
`pancakes` crate needing to implement it; the `#[derive(HelloMacro)]` added the
trait implementation.
### Attribute-like macros
Attribute-like macros are similar to custom derive macros, but instead of
generating code for `#[derive]`, they allow you to create new, custom
attributes of your own. They're also more flexible; derive only works for
structs and enums; attributes can go on other places as well, like functions.
As an example of using an attribute-like macro, you might have something like
this when using a web application framework:
```rust,ignore
#[route(GET, "/")]
fn index() {
```
This `#[route]` attribute would be defined by the framework itself, as a
procedural macro. Its signature would look like this:
```rust,ignore
#[proc_macro_attribute]
pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
```
Here, we have two input `TokenStream`s; the first is for the contents of the
attribute itself, that is, the `GET, "/"` stuff. The second is the body of
the thing the attribute is attached to, in this case, `fn index() {}` and the
rest of the function's body.
Other than that, they work the same way: create a crate with the `proc-macro`
crate type, and you're good to go!
### Function-like macros
Finally, function-like macros define macros that look like function calls. For
example, an `sql!` macro:
```rust,ignore
let sql = sql!(SELECT * FROM posts WHERE id=1);
```
This macro would parse the SQL statement inside of it and check that it's
syntactically correct. This macro would be defined like this:
```rust,ignore
#[proc_macro]
pub fn sql(input: TokenStream) -> TokenStream {
```
This is similar to the derive macro's signature: we get in the tokens that are
inside of the parentheses, and return the code we wanted to generate.

View File

@ -482,7 +482,7 @@ returned a `ThreadPool` instance containing them.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,not_desired_behavior
use std::thread;
pub struct ThreadPool {
@ -727,7 +727,7 @@ the closure. The code in Listing 20-17 wont quite compile yet.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
impl ThreadPool {
// --snip--
pub fn new(size: usize) -> ThreadPool {
@ -891,7 +891,7 @@ types shorter. Look at Listing 20-19.
# use std::sync::mpsc;
# struct Worker {}
type Job = Box<dyn FnOnce() + Send + 'static>;
type Job = Box<FnOnce() + Send + 'static>;
impl ThreadPool {
// --snip--
@ -929,7 +929,7 @@ shown in Listing 20-20 to `Worker::new`.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
// --snip--
impl Worker {
@ -995,11 +995,11 @@ the value inside the `Box<T>` will be: recall in Chapter 15 that we used
to store in a `Box<T>` to get a value of a known size.
As you saw in Listing 17-15, we can write methods that use the syntax `self:
Box<dyn Self>`, which allows the method to take ownership of a `Self` value stored
Box<Self>`, which allows the method to take ownership of a `Self` value stored
in a `Box<T>`. Thats exactly what we want to do here, but unfortunately Rust
wont let us: the part of Rust that implements behavior when a closure is
called isnt implemented using `self: Box<dyn Self>`. So Rust doesnt yet
understand that it could use `self: Box<dyn Self>` in this situation to take
called isnt implemented using `self: Box<Self>`. So Rust doesnt yet
understand that it could use `self: Box<Self>` in this situation to take
ownership of the closure and move the closure out of the `Box<T>`.
Rust is still a work in progress with places where the compiler could be
@ -1009,9 +1009,9 @@ finished this book, we would love for you to join in.
But for now, lets work around this problem using a handy trick. We can tell
Rust explicitly that in this case we can take ownership of the value inside the
`Box<T>` using `self: Box<dyn Self>`; then, once we have ownership of the closure,
`Box<T>` using `self: Box<Self>`; then, once we have ownership of the closure,
we can call it. This involves defining a new trait `FnBox` with the method
`call_box` that will use `self: Box<dyn Self>` in its signature, defining `FnBox`
`call_box` that will use `self: Box<Self>` in its signature, defining `FnBox`
for any type that implements `FnOnce()`, changing our type alias to use the new
trait, and changing `Worker` to use the `call_box` method. These changes are
shown in Listing 20-21.
@ -1029,7 +1029,7 @@ impl<F: FnOnce()> FnBox for F {
}
}
type Job = Box<dyn FnBox + Send + 'static>;
type Job = Box<FnBox + Send + 'static>;
// --snip--
@ -1054,11 +1054,11 @@ impl Worker {
```
<span class="caption">Listing 20-21: Adding a new trait `FnBox` to work around
the current limitations of `Box<dyn FnOnce()>`</span>
the current limitations of `Box<FnOnce()>`</span>
First, we create a new trait named `FnBox`. This trait has the one method
`call_box`, which is similar to the `call` methods on the other `Fn*` traits
except that it takes `self: Box<dyn Self>` to take ownership of `self` and move the
except that it takes `self: Box<Self>` to take ownership of `self` and move the
value out of the `Box<T>`.
Next, we implement the `FnBox` trait for any type `F` that implements the
@ -1136,7 +1136,7 @@ why we didnt write the worker thread code as shown in Listing 20-22.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,not_desired_behavior
// --snip--
impl Worker {

View File

@ -23,7 +23,7 @@ quite work yet.
<span class="filename">Filename: src/lib.rs</span>
```rust,ignore
```rust,ignore,does_not_compile
impl Drop for ThreadPool {
fn drop(&mut self) {
for worker in &mut self.workers {
@ -59,7 +59,7 @@ The error tells us we cant call `join` because we only have a mutable borrow
of each `worker` and `join` takes ownership of its argument. To solve this
issue, we need to move the thread out of the `Worker` instance that owns
`thread` so `join` can consume the thread. We did this in Listing 17-15: if
`Worker` holds an `Option<thread::JoinHandle<()>` instead, we can call the
`Worker` holds an `Option<thread::JoinHandle<()>>` instead, we can call the
`take` method on the `Option` to move the value out of the `Some` variant and
leave a `None` variant in its place. In other words, a `Worker` that is running
will have a `Some` variant in `thread`, and when we want to clean up a

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1259px" height="847px" viewBox="0 0 1259 847" enable-background="new 0 0 1259 847" xml:space="preserve">
<!--<rect fill="#FFFFFF" width="1259" height="847"/>-->
<path fill="#8F1F1D" d="M706.403,338.05c-131.633,0-251.228,15.825-339.77,41.615v220.298
c88.542,25.79,208.137,41.614,339.77,41.614c150.657,0,285.535-20.729,376.134-53.402V391.457
C991.938,358.781,857.06,338.05,706.403,338.05"/>
<path fill="#8F1F1D" d="M1088.423,537.442c-3.856-10.663-4.629-24.154-1.36-37.162c5.85-23.289,22.421-36.198,37.013-28.833
c3.618,1.827,6.773,4.73,9.387,8.418c0.239-0.001,0.479,0,0.715,0.016c0,0,44.552,53.106,3.313,116.003
c-0.896,3.569-76.534,91.718-94.043,94.524C1031.987,692.244,1058.338,600.41,1088.423,537.442"/>
<path fill="#8F1F1D" d="M357.479,527.021c5.3-9.631,7.158-22.788,4.217-36.426c-5.266-24.416-23.91-41.109-41.642-37.285
c-4.398,0.948-8.325,3.072-11.666,6.099c-0.282-0.059-0.564-0.113-0.845-0.153c0,0-56.292,41.952-12.057,113.924
c0.805,3.741,83.851,108.838,104.311,115.764C413.188,693.475,388.55,596.418,357.479,527.021"/>
<path fill="#E23A26" d="M280.467,535.066l0.007,0.015C280.659,535.226,280.831,535.357,280.467,535.066"/>
<path fill="#E33B26" d="M1174.119,457.903c-0.88-3.064-1.756-6.126-2.662-9.162l30.683-44.451c3.13-4.522,3.771-10.398,1.73-15.555
c-2.04-5.13-6.49-8.81-11.76-9.71l-51.887-8.805c-2.008-4.102-4.115-8.142-6.229-12.15l21.797-49.903
c2.243-5.087,1.769-10.995-1.203-15.608c-2.961-4.636-7.99-7.344-13.349-7.133l-52.656,1.913c-2.727-3.55-5.496-7.068-8.322-10.521
l12.102-53.49c1.225-5.433-0.322-11.118-4.104-15.064c-3.762-3.932-9.229-5.559-14.426-4.283l-51.289,12.608
c-3.321-2.935-6.699-5.833-10.114-8.673l1.849-54.914c0.197-5.559-2.394-10.842-6.845-13.925
c-4.445-3.104-10.093-3.573-14.955-1.266l-47.848,22.747c-3.854-2.21-7.728-4.4-11.644-6.517l-8.455-54.115
c-0.857-5.483-4.386-10.139-9.326-12.266c-4.923-2.137-10.568-1.447-14.891,1.808l-42.659,32.007
c-4.2-1.395-8.419-2.732-12.692-4.011l-18.386-51.316c-1.87-5.229-6.182-9.071-11.438-10.151c-5.238-1.072-10.63,0.742-14.263,4.802
L764.97,100.97c-4.342-0.5-8.685-0.956-13.043-1.331l-27.723-46.713c-2.811-4.732-7.771-7.612-13.116-7.612
c-5.334,0-10.304,2.88-13.09,7.612l-27.733,46.713c-4.358,0.375-8.722,0.831-13.056,1.331l-35.91-40.171
c-3.636-4.06-9.047-5.874-14.268-4.802c-5.255,1.092-9.573,4.922-11.433,10.151l-18.402,51.316
c-4.26,1.279-8.481,2.627-12.691,4.011l-42.644-32.007c-4.336-3.266-9.98-3.955-14.916-1.808c-4.919,2.127-8.461,6.783-9.313,12.266
l-8.461,54.115c-3.914,2.117-7.789,4.294-11.653,6.517l-47.842-22.747c-4.858-2.316-10.529-1.838-14.954,1.266
c-4.445,3.083-7.042,8.366-6.84,13.925l1.835,54.914c-3.405,2.84-6.774,5.738-10.112,8.673l-51.279-12.608
c-5.211-1.265-10.67,0.351-14.441,4.283c-3.795,3.946-5.332,9.631-4.113,15.064l12.079,53.49c-2.802,3.467-5.575,6.971-8.293,10.521
l-52.655-1.913c-5.314-0.157-10.386,2.497-13.356,7.133c-2.974,4.613-3.425,10.521-1.211,15.608l21.814,49.903
c-2.119,4.008-4.224,8.048-6.249,12.15l-51.882,8.805c-5.271,0.888-9.715,4.566-11.765,9.71c-2.037,5.157-1.375,11.033,1.735,15.555
l30.69,44.451c-0.236,0.784-0.455,1.576-0.69,2.364l-16.863,17.911l45.341,64.05c0,0,435.152,200.731,838.797,3.396
C1163.372,528.189,1174.119,457.903,1174.119,457.903"/>
<path d="M788.629,436.277c0,0,54.108-46.602,95.626,11.5c0,0,29.173,74.328-12.593,104.708c0,0-67.353,41.473-95.627-11.5
C776.035,540.985,739.67,497.66,788.629,436.277"/>
<path fill="#FFFFFF" d="M843.648,464.356c-2.452,20.385-16.456,35.467-31.276,33.684c-14.817-1.781-24.846-19.755-22.395-40.14
c2.452-20.385,16.457-35.468,31.274-33.687C836.071,425.997,846.1,443.971,843.648,464.356"/>
<path d="M572.949,399.315c0,0,86.384-26.449,99.021,57.297c0,0,12.086,97.294-79.356,91.705
C592.613,548.317,479.508,512.09,572.949,399.315"/>
<rect x="181" y="45" fill="none" width="1060" height="782"/>
<path fill="#FFFFFF" d="M611.925,441.324c-2.528,21.021-16.969,36.581-32.257,34.742c-15.281-1.837-25.624-20.378-23.095-41.399
c2.529-21.026,16.973-36.581,32.253-34.743C604.113,401.763,614.454,420.298,611.925,441.324"/>
<path fill="#E33B26" d="M292.602,544.216c10.967-12.463,37.611-27.557,35.57-46.282c-3.653-33.526-31.456-57.999-62.099-54.658
c-7.599,0.827-14.658,3.292-20.923,7.035c-0.463-0.106-0.925-0.211-1.388-0.294c0,0-103.632,50.873-44.564,152.657
c0.557,5.137,117.847,155.668,150.787,167.131C371.544,777.307,330.074,641.165,292.602,544.216"/>
<path fill="#E33B26" d="M1134.549,539.673c-12.692-10.7-46.162-20.418-46.92-39.238c-1.355-33.697,22.512-62.021,53.312-63.26
c7.638-0.308,14.983,1.083,21.734,3.857c0.442-0.174,0.884-0.347,1.329-0.497c0,0,110.025,34.951,66.695,144.366
c0.21,5.163-93.468,171.416-124.345,187.635C1086.146,783.151,1111.861,641.105,1134.549,539.673"/>
<rect x="181.06" y="45.314" fill="none" width="1059.75" height="781.686"/>
<path fill="#E33B26" d="M372.142,545.559c0,0-1.383,137.296,133.166,167.933l28.054-56.363c0,0-97.495,9.431-104.995-111.569
H372.142"/>
<rect x="181" y="45" fill="none" width="1060" height="782"/>
<path fill="#E33B26" d="M1057.362,537.246c0,0,1.382,137.296-133.167,167.933l-28.055-56.363c0,0,97.495,9.431,104.995-111.569
H1057.362"/>
<path fill="#E33B26" d="M960.167,677.279c-20.25-48.941-85.595-68.373-145.951-43.399c-53.126,21.98-84.637,71.031-77.624,115.845
c41.946-0.652,86.94-3.371,130.736-9.718c0,0-25.837,41.763-63.857,78.211c25.566,6.599,55.383,4.768,84.076-7.104
C947.904,786.141,980.417,726.221,960.167,677.279"/>
<path fill="#E33B26" d="M585.746,745.985c0,0,55.203,7.295,130.67,9.155c6.61-47.511-29.38-97.792-86.801-117.242
c-63.438-21.488-128.989,2.792-146.414,54.231c-17.425,51.44,19.876,110.561,83.314,132.049
c28.121,9.526,56.653,10.049,81.229,3.207C610.833,790.881,585.746,745.985,585.746,745.985"/>
<rect x="181.06" y="45.314" fill="none" width="1059.75" height="781.686"/>
<g>
<path d="M92.314,318.146l0.072-12.563c-0.359-24.665,8.95-49.384,31.787-73.989c16.267-18.129,29.512-33.493,30.216-49.411
c0.747-16.883-9.835-28.95-33.932-30.499c-15.918-0.704-35.468,4.231-48.394,12.359l-14.075-53.303
c18.296-9.34,47.182-17.729,81.429-16.214c63.672,2.816,91.538,39.33,89.768,79.366c-1.621,36.659-25.84,59.753-45.066,79.202
c-18.24,19.009-26.789,37.48-27.267,59.207l-0.384,8.683L92.314,318.146z M76.808,384.64c1.152-26.048,19.789-43.105,44.872-41.997
c26.047,1.152,42.14,19.746,41.471,45.815c-1.109,25.083-18.824,43.148-45.353,41.975C92.232,429.303,75.698,409.723,76.808,384.64
z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1354px" height="819px" viewBox="0 0 1354 819" enable-background="new 0 0 1354 819" xml:space="preserve">
<!--<rect fill="#FFFFFF" width="1354" height="819"/>-->
<path fill="#8F1F1D" d="M803.403,312.05c-131.633,0-251.228,15.825-339.77,41.615v220.298
c88.542,25.79,208.137,41.614,339.77,41.614c150.657,0,285.535-20.729,376.134-53.402V365.457
C1088.938,332.781,954.06,312.05,803.403,312.05"/>
<path fill="#8F1F1D" d="M1185.423,511.442c-3.856-10.663-4.629-24.154-1.36-37.162c5.85-23.289,22.421-36.198,37.013-28.833
c3.618,1.827,6.773,4.73,9.387,8.418c0.239-0.001,0.479,0,0.715,0.016c0,0,44.552,53.106,3.313,116.003
c-0.896,3.569-76.534,91.718-94.043,94.524C1128.987,666.244,1155.338,574.41,1185.423,511.442"/>
<path fill="#8F1F1D" d="M454.479,501.021c5.3-9.631,7.158-22.788,4.217-36.426c-5.266-24.416-23.91-41.109-41.642-37.285
c-4.398,0.948-8.325,3.072-11.666,6.099c-0.282-0.059-0.564-0.113-0.845-0.153c0,0-56.292,41.952-12.057,113.924
c0.805,3.741,83.851,108.838,104.311,115.764C510.188,667.475,485.55,570.418,454.479,501.021"/>
<path fill="#E23A26" d="M375.467,507.066l0.007,0.015C375.659,507.226,375.831,507.357,375.467,507.066"/>
<path fill="#E33B26" d="M1271.119,431.903c-0.88-3.064-1.756-6.126-2.662-9.162l30.683-44.451c3.13-4.522,3.771-10.398,1.73-15.555
c-2.04-5.13-6.49-8.81-11.76-9.71l-51.887-8.805c-2.008-4.102-4.115-8.142-6.229-12.15l21.797-49.903
c2.243-5.087,1.769-10.995-1.203-15.608c-2.961-4.636-7.99-7.344-13.349-7.133l-52.656,1.913c-2.727-3.55-5.496-7.068-8.322-10.521
l12.102-53.49c1.225-5.433-0.322-11.118-4.104-15.064c-3.762-3.932-9.229-5.559-14.426-4.283l-51.289,12.608
c-3.321-2.935-6.699-5.833-10.114-8.673l1.849-54.914c0.197-5.559-2.394-10.842-6.845-13.925
c-4.445-3.104-10.093-3.573-14.955-1.266l-47.848,22.747c-3.854-2.21-7.728-4.4-11.644-6.517l-8.455-54.115
c-0.857-5.483-4.386-10.139-9.326-12.266c-4.923-2.137-10.568-1.447-14.891,1.808l-42.659,32.007
c-4.2-1.395-8.419-2.732-12.692-4.011l-18.386-51.316c-1.87-5.229-6.182-9.071-11.438-10.151c-5.238-1.072-10.63,0.742-14.263,4.802
L861.97,74.97c-4.342-0.5-8.685-0.956-13.043-1.331l-27.723-46.713c-2.811-4.732-7.771-7.612-13.116-7.612
c-5.334,0-10.304,2.88-13.09,7.612l-27.733,46.713c-4.358,0.375-8.722,0.831-13.056,1.331l-35.91-40.171
c-3.636-4.06-9.047-5.874-14.268-4.802c-5.255,1.092-9.573,4.922-11.433,10.151l-18.402,51.316
c-4.26,1.279-8.481,2.627-12.691,4.011l-42.644-32.007c-4.336-3.266-9.98-3.955-14.916-1.808c-4.919,2.127-8.461,6.783-9.313,12.266
l-8.461,54.115c-3.914,2.117-7.789,4.294-11.653,6.517l-47.842-22.747c-4.858-2.316-10.529-1.838-14.954,1.266
c-4.445,3.083-7.042,8.366-6.84,13.925l1.835,54.914c-3.405,2.84-6.774,5.738-10.112,8.673l-51.279-12.608
c-5.211-1.265-10.67,0.351-14.441,4.283c-3.795,3.946-5.332,9.631-4.113,15.064l12.079,53.49c-2.802,3.467-5.575,6.971-8.293,10.521
l-52.655-1.913c-5.314-0.157-10.386,2.497-13.356,7.133c-2.974,4.613-3.425,10.521-1.211,15.608l21.814,49.903
c-2.119,4.008-4.224,8.048-6.249,12.15l-51.882,8.805c-5.271,0.888-9.715,4.566-11.765,9.71c-2.037,5.157-1.375,11.033,1.735,15.555
l30.69,44.451c-0.236,0.784-0.455,1.576-0.69,2.364l-16.863,17.911l45.341,64.05c0,0,435.152,200.731,838.797,3.396
C1260.372,502.189,1271.119,431.903,1271.119,431.903"/>
<path d="M886.303,395.759c0,0,48.157-52.729,96.315,0c0,0,37.84,70.312,0,105.463c0,0-61.917,49.218-96.315,0
C886.303,501.222,845.024,462.55,886.303,395.759"/>
<path fill="#FFFFFF" d="M942.057,415.32c0,20.532-12.103,37.179-27.029,37.179c-14.924,0-27.027-16.646-27.027-37.179
s12.104-37.18,27.027-37.18C929.954,378.14,942.057,394.788,942.057,415.32"/>
<path d="M671.365,381.361c0,0,82.608-36.576,105.154,45.062c0,0,23.618,95.154-67.837,100.525
C708.682,526.948,592.06,504.486,671.365,381.361"/>
<rect x="278" y="19" fill="none" width="1060" height="782"/>
<g>
<defs>
<rect id="SVGID_1_" x="278.06" y="19.314" width="1059.75" height="781.686"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<path clip-path="url(#SVGID_2_)" fill="#FFFFFF" d="M712.855,416.668c0,21.173-12.48,38.346-27.877,38.346
c-15.391,0-27.874-17.173-27.874-38.346c0-21.178,12.483-38.346,27.874-38.346C700.375,378.322,712.855,395.49,712.855,416.668"/>
<path clip-path="url(#SVGID_2_)" fill="#E33B26" d="M389.602,518.216c10.967-12.463,37.611-27.557,35.57-46.282
c-3.653-33.526-31.456-57.999-62.099-54.658c-7.599,0.827-14.658,3.292-20.923,7.035c-0.463-0.106-0.925-0.211-1.388-0.294
c0,0-103.632,50.873-44.564,152.657c0.557,5.137,117.847,155.668,150.787,167.131C468.544,751.307,427.074,615.165,389.602,518.216
"/>
<path clip-path="url(#SVGID_2_)" fill="#E33B26" d="M1231.549,513.673c-12.692-10.7-46.162-20.418-46.92-39.238
c-1.355-33.697,22.512-62.021,53.312-63.26c7.638-0.308,14.983,1.083,21.734,3.857c0.442-0.174,0.884-0.347,1.329-0.497
c0,0,110.025,34.951,66.695,144.366c0.21,5.163-93.468,171.416-124.345,187.635
C1183.146,757.151,1208.861,615.105,1231.549,513.673"/>
</g>
<rect x="278" y="19" fill="none" width="1060" height="782"/>
<path fill="#E33B26" d="M1154.362,514.558c0,0,1.382,137.296-133.167,167.933l-28.055-56.363c0,0,97.495,9.431,104.995-111.569
H1154.362"/>
<path fill="#E33B26" d="M1057.167,654.591c-20.25-48.941-85.595-68.373-145.951-43.399c-53.126,21.98-84.637,71.031-77.624,115.845
c41.946-0.652,86.94-3.371,130.736-9.718c0,0-25.837,41.763-63.857,78.211c25.566,6.599,55.383,4.768,84.076-7.104
C1044.904,763.452,1077.417,703.532,1057.167,654.591"/>
<g>
<path fill="#E33B26" d="M396.635,512.763c0,0-120.426,65.951-210.88-38.262l36.479-51.313c0,0,37.649,90.426,147.893,39.991
L396.635,512.763"/>
<path fill="#E33B26" d="M144.038,392.655c0,0-46.915-29.995-114.487-63.65C3.436,369.241,14.735,430.034,58.509,471.979
c48.361,46.34,118.025,52.115,155.601,12.901c37.576-39.214,28.833-108.569-19.528-154.908
c-21.437-20.543-47.061-33.103-72.221-37.316C140.333,341.359,144.038,392.655,144.038,392.655"/>
</g>
<rect x="278.06" y="19.314" fill="none" width="1059.75" height="781.686"/>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1434.979px" height="947px" viewBox="0 0 1434.979 947" enable-background="new 0 0 1434.979 947" xml:space="preserve">
<!--<rect fill="#FFFFFF" width="1434.979" height="947"/>-->
<path fill="#8F1F1D" d="M712.827,368.579c-131.633,0-251.228,15.825-339.77,41.615v220.298
c88.542,25.79,208.137,41.614,339.77,41.614c150.657,0,285.535-20.729,376.134-53.402V421.986
C998.361,389.311,863.483,368.579,712.827,368.579"/>
<path fill="#8F1F1D" d="M1094.847,567.972c-3.856-10.663-4.629-24.154-1.36-37.162c5.85-23.289,22.421-36.198,37.013-28.833
c3.618,1.827,6.773,4.73,9.387,8.418c0.239-0.001,0.479,0,0.715,0.016c0,0,44.552,53.106,3.313,116.003
c-0.896,3.569-76.534,91.718-94.043,94.524C1038.411,722.773,1064.762,630.939,1094.847,567.972"/>
<path fill="#8F1F1D" d="M363.903,557.551c5.3-9.631,7.158-22.788,4.217-36.426c-5.266-24.416-23.91-41.109-41.642-37.285
c-4.398,0.948-8.325,3.072-11.666,6.099c-0.282-0.059-0.564-0.113-0.845-0.153c0,0-56.292,41.952-12.057,113.924
c0.805,3.741,83.851,108.838,104.311,115.764C419.612,724.004,394.974,626.947,363.903,557.551"/>
<path fill="#E23A26" d="M284.891,563.596l0.007,0.015C285.083,563.755,285.255,563.887,284.891,563.596"/>
<path fill="#E33B26" d="M1180.543,488.433c-0.88-3.064-1.756-6.126-2.662-9.162l30.683-44.451c3.13-4.522,3.771-10.398,1.73-15.555
c-2.04-5.13-6.49-8.81-11.76-9.71l-51.887-8.805c-2.008-4.102-4.115-8.142-6.229-12.15l21.797-49.903
c2.243-5.087,1.769-10.995-1.203-15.608c-2.961-4.636-7.99-7.344-13.349-7.133l-52.656,1.913c-2.727-3.55-5.496-7.068-8.322-10.521
l12.102-53.49c1.225-5.433-0.322-11.118-4.104-15.064c-3.762-3.932-9.229-5.559-14.426-4.283l-51.289,12.608
c-3.321-2.935-6.699-5.833-10.114-8.673l1.849-54.914c0.197-5.559-2.394-10.842-6.845-13.925
c-4.445-3.104-10.093-3.573-14.955-1.266l-47.848,22.747c-3.854-2.21-7.728-4.4-11.644-6.517l-8.455-54.115
c-0.857-5.483-4.386-10.139-9.326-12.266c-4.923-2.137-10.568-1.447-14.891,1.808l-42.659,32.007
c-4.2-1.395-8.419-2.732-12.692-4.011l-18.386-51.316c-1.87-5.229-6.182-9.071-11.438-10.151c-5.238-1.072-10.63,0.742-14.263,4.802
l-35.907,40.171c-4.342-0.5-8.685-0.956-13.043-1.331l-27.723-46.713c-2.811-4.732-7.771-7.612-13.116-7.612
c-5.334,0-10.304,2.88-13.09,7.612l-27.733,46.713c-4.358,0.375-8.722,0.831-13.056,1.331l-35.91-40.171
c-3.636-4.06-9.047-5.874-14.268-4.802c-5.255,1.092-9.573,4.922-11.433,10.151l-18.402,51.316
c-4.26,1.279-8.481,2.627-12.691,4.011l-42.644-32.007c-4.336-3.266-9.98-3.955-14.916-1.808c-4.919,2.127-8.461,6.783-9.313,12.266
l-8.461,54.115c-3.914,2.117-7.789,4.294-11.653,6.517L436.1,168.34c-4.858-2.316-10.529-1.838-14.954,1.266
c-4.445,3.083-7.042,8.366-6.84,13.925l1.835,54.914c-3.405,2.84-6.774,5.738-10.112,8.673L354.75,234.51
c-5.211-1.265-10.67,0.351-14.441,4.283c-3.795,3.946-5.332,9.631-4.113,15.064l12.079,53.49c-2.802,3.467-5.575,6.971-8.293,10.521
l-52.655-1.913c-5.314-0.157-10.386,2.497-13.356,7.133c-2.974,4.613-3.425,10.521-1.211,15.608l21.814,49.903
c-2.119,4.008-4.224,8.048-6.249,12.15l-51.882,8.805c-5.271,0.888-9.715,4.566-11.765,9.71c-2.037,5.157-1.375,11.033,1.735,15.555
l30.69,44.451c-0.236,0.784-0.455,1.576-0.69,2.364l-16.863,17.911l45.341,64.05c0,0,435.152,200.731,838.797,3.396
C1169.796,558.719,1180.543,488.433,1180.543,488.433"/>
<path d="M795.716,446.557c0,0,48.162-52.734,96.324,0c0,0,37.844,70.318,0,105.473c0,0-61.922,49.223-96.324,0
C795.716,552.029,754.434,513.354,795.716,446.557"/>
<path fill="#FFFFFF" d="M855.154,481.097c0,19.782-11.66,35.82-26.041,35.82c-14.379,0-26.04-16.038-26.04-35.82
c0-19.782,11.661-35.821,26.04-35.821C843.494,445.275,855.154,461.315,855.154,481.097"/>
<path d="M578.401,430.129c0,0,84.436-37.385,107.481,46.059c0,0,24.141,97.261-69.339,102.751
C616.543,578.939,497.34,555.98,578.401,430.129"/>
<rect x="187.424" y="75.529" fill="none" width="1060" height="782"/>
<path fill="#FFFFFF" d="M627.514,481.096c0,20.579-12.13,37.27-27.095,37.27c-14.959,0-27.092-16.69-27.092-37.27
c0-20.583,12.133-37.27,27.092-37.27C615.384,443.826,627.514,460.513,627.514,481.096"/>
<path fill="#E33B26" d="M299.026,574.745c10.967-12.463,37.611-27.557,35.57-46.282c-3.653-33.526-31.456-57.999-62.099-54.658
c-7.599,0.827-14.658,3.292-20.923,7.035c-0.463-0.106-0.925-0.211-1.388-0.294c0,0-103.632,50.873-44.564,152.657
c0.557,5.137,117.847,155.668,150.787,167.131C377.968,807.836,336.498,671.694,299.026,574.745"/>
<path fill="#E33B26" d="M1140.973,570.202c-12.692-10.7-46.162-20.418-46.92-39.238c-1.355-33.697,22.512-62.021,53.312-63.26
c7.638-0.308,14.983,1.083,21.734,3.857c0.442-0.174,0.884-0.347,1.329-0.497c0,0,110.025,34.951,66.695,144.366
c0.21,5.163-93.468,171.416-124.345,187.635C1092.57,813.681,1118.285,671.635,1140.973,570.202"/>
<rect x="187.484" y="75.843" fill="none" width="1059.75" height="781.686"/>
<rect x="187.424" y="75.529" fill="none" width="1060" height="782"/>
<g>
<path fill="#E33B26" d="M283.144,565.511c0,0-137.214-4.942-161.62-140.761l57.596-25.427c0,0-13.912,96.957,106.615,110.022
L283.144,565.511"/>
<path fill="#E33B26" d="M127.552,333.083c0,0-24.965-49.774-65.807-113.261C18.721,241.035-2.671,299.05,13.482,357.484
c17.846,64.558,74.749,105.16,127.097,90.69s80.318-78.535,62.471-143.092c-7.909-28.618-23.501-52.519-42.963-69.011
C150.611,287.113,127.552,333.083,127.552,333.083"/>
</g>
<rect x="187.484" y="75.843" fill="none" width="1059.75" height="781.686"/>
<g>
<path fill="#E33B26" d="M1148.012,565.511c0,0,137.214-4.942,161.62-140.761l-57.596-25.428c0,0,13.912,96.957-106.615,110.022
L1148.012,565.511"/>
<path fill="#E33B26" d="M1303.604,333.083c0,0,24.966-49.774,65.808-113.261c43.023,21.212,64.416,79.228,48.262,137.662
c-17.846,64.558-74.748,105.16-127.096,90.689c-52.348-14.47-80.318-78.534-62.472-143.091
c7.909-28.618,23.501-52.519,42.964-69.011C1280.544,287.113,1303.604,333.083,1303.604,333.083"/>
</g>
<path d="M807.895,626.942c-7.131-58.735-72.193-61.431-72.193-61.431c-50.936,11.227-59.183,47.369-57.392,75.104L807.895,626.942z"
/>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1,291 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1240.298px" height="811.376px" viewBox="0 0 1240.298 811.376" enable-background="new 0 0 1240.298 811.376"
xml:space="preserve">
<!--<rect fill="#FFFFFF" width="1240.298" height="811.376"/>-->
<rect x="303.062" y="408.688" fill="#E33D27" width="440" height="322.312"/>
<polygon fill="#F37056" points="548.062,459 543.062,491 595.48,475 631.558,487 620.149,516.493 673.576,524.134 713.745,584
700.062,644.844 753.914,671 780.201,542.318 678.062,433.837 "/>
<ellipse fill="#FFFFFF" cx="456.505" cy="603.308" rx="20.83" ry="41.536"/>
<ellipse fill="#FFFFFF" cx="613.519" cy="599.293" rx="18.039" ry="25.608"/>
<path d="M426.848,565.302c76.475-36.052,82.274,92.731,23.019,92.075C407.91,656.909,399.502,592.939,426.848,565.302z
M472.886,588.319c-3.647-13.308-14.517-15.274-25.896-8.632C411.107,600.633,485.029,632.633,472.886,588.319z"/>
<path d="M593.734,565.302c63.543-6.768,43.711,98.739,0,97.828C549.726,662.215,539.183,571.111,593.734,565.302z M616.753,614.216
c8.869-6.019,6.418-24.879,0-31.65C586.653,575.41,587.316,620.858,616.753,614.216z"/>
<path fill="#E33D27" d="M1218.119,680.395c7.154,1.962-4.255,8.762-5.754,11.51c-40.783-1.407-71.586-8.146-97.83,5.754
c-14.517-1.252-39.852-13.043-46.037,2.878c14.931,25.351,67.049,13.519,89.197,31.651c-12.87,18.54-39.345,5.012-57.547,5.754
c-10.099,0.416-19.838,5.935-28.774,5.755c-49.039-0.988-101.843-22.372-152.498-23.019c42.625,23.559,115.104,17.253,155.376,43.16
c-67.472,4.49-120.696-26.278-187.028-17.264c-6.34,0.861-6.592,6.33-11.509,5.754c-13.465-1.579-23.525-15.382-40.283-5.754
c-6.26,5.23,6.261,17.787,0,23.018c-15.253-0.503-14.684-1.859-28.772,0c8.165-6.89,2.844-10.598,2.877-23.018
c-13.752,2.551-9.706,22.902-25.896,23.018c-10.812-10.287-27.408-14.791-37.405-25.896c-12.972,3.333-5.671,26.937-17.265,31.65
c-14.173-3.091-17.477-17.048-23.019-28.772c-3.136,10.441-20.8,16.528-28.773,5.754c-2.085,8.801,4.968,8.464,2.878,17.264
c-18.137,3.755-22.952-5.821-37.406-5.754c0.949-12.456-3.963-19.055-11.51-23.019c4.176,9.359,9.97,28.835,2.877,40.283
c58.823,6.435-102.298,3.786-184.15,5.755c-4.103-3.839-4.103-16.305,0-20.142c-3.242-3.983-16.786,6.063-25.896,5.754
c-3.692-3.776-3.692-10.61,0-14.387c-22.912,6.714-41.991-16.95-51.792,2.878c-22.355-21.002-38.624,9.456-63.301,11.509
c-0.208-9.795,8.463-10.717,14.387-14.387c-1.225-5.487-8.217-5.209-5.754-14.387c-21.833-0.735-30.381,11.819-48.916,14.387
c-6.676-6.637,5.328-9.278,2.878-20.142c-14.78-4.791-23.536,24.911-43.161,14.387c2.484-8.068,14.983-6.119,20.142-11.509
c-4.107-7.834-13.948-3.709-28.773-5.756c5.839-11.424,18.647-15.887,28.773-23.018c-16.19-14.891-50.252,8.151-86.32,0
c-5.632-5.376-0.888-10.538,0-17.264c-26.711,2.744-56.57-2.806-92.075,0c2.416-3.342,3.799-7.716,2.877-14.388
c21.001-2.978,57.323,9.365,57.547-14.387c13.15,2.023,39.985,15.118,48.916,2.878c-41.733-18.691-93.205-27.639-132.358-48.915
c46.858-1.271,84.578,2.139,123.726-2.877c-14.836-7.225-29.161-14.957-51.792-14.387c-1.995-9.515-8.025-14.992-14.387-20.142
c14.393,0.544,26.632,3.115,37.406-11.511c-28.684-5.917-66.629-11.896-103.584-17.264c-0.489-8.162,9.733-5.614,5.754-17.264
c44.335,1.66,97.286,27.155,149.623,20.142c-19.613-10.115-54.625-4.845-74.811-14.387c8.817-3.917,31.875,2.574,48.915,0
c-28.055-9.265-51.18-14.974-74.811-23.02c-1.147-10.739,2.299-16.882,11.509-17.264c-27.891-14.312-72.805-11.593-92.075-34.528
c67.275,12.083,131.448,13.792,198.537,25.897c-37.895-23.488-109.193-13.576-135.235-48.916
c17.298,3.808,38.108,4.095,51.792,11.509c5.26-4.333,6.772-12.414,11.51-17.263c-8.29-12.375-29.769-25.14-28.774-37.406
c-10.126,8.26-21.226,0.57-11.509-8.633c-6.558-0.802-10.812,0.695-11.509,5.755c-11.38-14.192-41.548-24.578-69.057-37.406
c13.712-22.602,48.516,23.597,60.424-8.632c37.523,18.628,73.715,39.315,117.971,57.547c7.57,0.851,2.265-11.164,11.509-8.631
c-30.864-42.024-97.425-48.358-123.726-94.953c55.422,11.463,96.745,35.034,138.113,48.915
c-18.522-26.558-67.382-47.704-100.707-69.056c16.719-7.501,46.628,10.534,66.179,25.896c17.062,0.757,22.496-4.753,28.773,5.755
c3.467-3.249,5.215-8.211,14.387-5.755c-2.417-17.223-41.047-27.381-34.528-34.528c-2.821-5.753-23.592,3.166-17.264-5.753
c17.021-8.622,52.713,19.045,71.934,34.528c8.856,2.143,5.53-7.898,14.386-5.755c-17.477-41.028-62.902-54.108-94.952-80.565
c16.101-2.625,34.859,16.896,48.915,25.896c-13.454-30.673-60.846-52.319-83.443-83.443c14.331-9.428,31.427,3.026,34.529,14.387
c41.625-17.209,41.851,53.044,83.443,54.67c0.135-9.789-20.698-23.374-23.019-40.283c55.417,21.313,74.771,78.69,120.848,109.339
c-9.694-14.366-16-28.587-25.896-40.283c-2.906-3.435-12.078-6.455-14.387-11.509c-5.181-11.351,2.501-24.23,0-37.405
c-8.834-46.596-59.648-77.024-71.934-126.604c60.424,23.635,64.139,87.271,120.849,112.217c3.502,9.927,9.508,17.348,17.264,23.019
c-6.501-27.068-24.469-42.668-31.65-69.057c13.105,16.627,22.53,36.939,34.528,54.669c7.923-3.45,12.021-6.249,20.142-2.877
c14.933,25.514,12.746,62.473,31.65,77.688c1.545-27.312-19.079-81.817-48.914-103.585c4.917-13.311,16.061,0.944,23.018,2.877
c-2.382-36.073-48.858-95.548-25.896-138.113c33.685,45.919,52.119,107.102,80.565,158.254c18.647-22.846-6.754-63.077-5.753-77.689
c24.345-6.629,23.125,36.008,34.528,51.793c-11.323,15.779-18.107,69.924,0,80.566c6.732-22.835,27.025-70.625,2.877-89.198
c11.532-27.307-11.375-85.412,5.754-115.095c2.333,0.547,2.873,2.886,5.755,2.878c11.375,8.951,6.991,52.885,14.387,74.811
c15.883-26.322,11.335-73.067,43.161-83.443c40.395,56.191,5.844,157.535,17.264,230.188c16.882-26.091,6.238-92.451,8.633-123.726
c12.835,6.351,2.354,36.013,5.753,51.792c9.999-29.156,17.749-76.621,8.633-100.707c31.206-12.896,6.732-68.573,40.283-74.811
c20.208,50.773-20.771,115.566,0,158.254c28.183-15.123,24.883-76.587,63.301-71.935c17.348-27.735,18.337-71.821,40.283-94.952
c11.599,6.23,6.939,20.636,5.755,28.774c-5.469,37.506-37.496,79.328-28.774,129.48c16.079,3.051,12.233-12.965,17.264-20.141
c22.969-32.747,53.524-54.615,63.303-97.83c9.093-4.339,13.37-13.492,23.02-17.264c2.972,30.808-14.271,66.28-31.652,86.321
c20.782,9.806,6.621,42.072,8.633,66.179c27.801-28.788,45.97-67.206,69.056-100.707c0.631-10.526,3.957-11.038,0-20.142
c9.694-4.023,12.285-19.592,25.896-11.51c-3.187,35.176-19.389,57.343-31.651,83.443c19.602,34.369-25.643,69.83-37.405,100.707
c36.49-22.017,56.587-60.427,83.443-92.075c15.522-3.715,22.333-31.311,37.406-25.896c10.121,10.746-15.416,33.993-28.774,40.283
c-15.814,24.466-37.271,43.289-54.67,66.18c20.4,0.253,19.901-20.384,34.528-25.897c-12.431,22.11-46.615,47.365-60.424,77.689
c19.49-10.264,44.7-39.687,60.424-63.302c5.48-5.392,7.232-0.313,14.388,0c31.863-23.788,69.443-45.422,60.423-94.952
c14.787-1.359,17.266,9.59,17.266,23.019c15.977-2.248,21.776-14.675,34.528-20.142c3.883,23.099-35.67,27.604-40.283,51.792
c7.024,7.731,17.86-5.038,23.019,5.755c-7.003,16.976-35.265,12.69-37.405,34.528c24.951,8.02,57.99-55.858,74.812-20.141
c-44.948,23.148-94.257,41.938-112.217,92.075c20.916,4.567,33.337-24.18,57.547-25.896c-15.781,11.964-9.128,30.528-25.896,43.16
c26.053-8.69,38.445-45.669,66.179-43.16c-21.068,16.015-36.569,16.525-51.792,48.915c22.496-2.73,53.81-20.786,80.566-28.773
c8.664,33.895-29.656,44.938-48.916,60.423c15.141,15.86,42.425,2.503,48.916-14.386c30.661,0.964,54.5-11.661,83.442-20.142
c-10.476,28.857-79.555,24.02-86.32,66.18c-17.449,3.649-25.379,16.821-43.161,20.142c22.188,0.098,49.978-19.061,77.689-23.019
c-21.384,16.979-53.405,23.318-74.812,40.283c4.153,13.752,14.089,3.931,23.02,0c18.343,0.12,34.905-1.545,43.159-11.51
c16.557,5.654,32.235-1.677,43.16-5.754c20.85,6.545,35.652,3.21,60.425,2.876c-9.054,14.494-47.628,12.643-51.792,40.283
c-15.404-1.017-20.782,7.991-31.651,11.509c-11.448-10.902-70.523-0.736-77.688,11.51c20.973,8.533,70.854-24.019,83.442,2.878
c-2.158,15.103-23.418,11.11-34.528,17.264c-0.917,7.632,16.124-2.691,11.509,8.632c-37.73-11.667-80.526,5.513-117.971,11.51
c54.85,5.668,118.797-17.455,166.887-11.51c-0.691,5.061-4.951,6.559-11.51,5.755c-1.102,9.736,12.739,4.527,8.633,17.264
c21.59,0.281,47.278-13.782,60.423,2.878c0.013,17.277-34.746-0.219-28.772,23.02c-36.653,4.706-80.122-7.428-103.584,14.386
c23.209,21.063,84.387-7.378,112.217,8.633c-10.348,14.589-38.198,11.672-60.425,14.387c-12.038,20.624-38.479,13.604-63.303,17.264
c16.473,25.356,71.062,17.585,94.953,20.142c3.191,5.446,3.67,13.594,5.755,20.141c-27.801,2.769-47.735,0.492-69.057,5.755
c37.866,18.388,83.977,14.851,135.235,28.774C1214.787,675.751,1214.787,688.616,1218.119,680.395z M550.575,202.755
c-2.799-24.018,5.136-64.358-2.877-74.811C546.247,154.524,529.809,185.218,550.575,202.755z M320.386,191.246
c-1,14.109,7.149,22.259,17.264,17.264C336.083,198.98,328.187,185.549,320.386,191.246z M662.79,266.057
c12.775-7.608,29.892-34.197,17.266-48.915C675.722,234.869,668.423,249.626,662.79,266.057z M349.16,243.038
c-8.98-2.527,0.106-23.126-11.51-23.019C336.487,230.921,344.479,247.532,349.16,243.038z M795.148,251.67
c3.984-9.588,28.605-22.207,14.388-31.651C805.719,229.717,784.224,236.792,795.148,251.67z M947.648,225.773
c-30.661,17.531-60.307,50.434-83.442,74.811c-7.183,7.567-21.355,17.894-17.266,25.897c33.73-34.37,81.348-54.849,106.463-97.831
C952.769,226.41,950.992,225.304,947.648,225.773z M524.678,300.584c-0.634-10.877,2.928-25.946-8.631-25.896
C510.319,282.514,512.819,301.348,524.678,300.584z M380.811,306.34c-8.363-6.98-10.779-19.912-20.142-25.896
C363.551,291.078,372.235,310.964,380.811,306.34z M766.376,355.254c11.79-17.008,36.512-36.346,37.405-54.67
C788.394,313.993,771.743,341.409,766.376,355.254z M228.311,335.113c-0.893-9.655-9.621-11.475-17.264-14.387
C208.473,333.853,220.511,332.365,228.311,335.113z M881.47,375.396c27.255-1.815,43.564-28.929,63.301-28.773
c-5.726-10.979,16.68-14.906,8.633-25.897C933.627,343.149,899.886,351.612,881.47,375.396z M950.526,340.868
c10.267-2.201,17.517-7.421,23.019-14.386C963.276,328.683,956.028,333.901,950.526,340.868z M832.554,366.763
c7.29-8.131,29.083-16.858,23.02-28.773C848.684,346.513,827.743,356.104,832.554,366.763z M513.169,378.273
c6.395-9.208,0.152-25.671-8.633-28.774C495.556,361.294,510.111,369.446,513.169,378.273z M259.962,407.046
c-0.961-12.467-15.933-10.918-23.019-17.264C239.416,400.739,247.216,406.369,259.962,407.046z M406.706,407.046
c-4.265-2.445-6.186-7.242-5.754-14.387C380.946,392.85,404.992,412.555,406.706,407.046z M1091.516,427.188
c18.889,1.254,40.199,5.823,51.792-5.755C1125.139,417.853,1105.779,418.069,1091.516,427.188z M861.328,467.471
c-4.401,8.843,18.793,8.843,14.387,0C874.979,460.736,863.076,465.812,861.328,467.471z M553.451,484.735
c9.801,0.208,10.718-8.465,14.388-14.387c-3.676-0.158-3.984-3.69-8.633-2.878C560.589,476.523,555.109,478.72,553.451,484.735z
M510.292,484.735c-7.593,9.672-6.013,28.515-25.897,25.896c-3.776-8.931,0.782-8.211,0-20.142
c-7.199,0.358-9.008,5.49-11.509-2.878c8.092-0.539,12.262-5.004,11.509-14.386c-10.543-0.954-15.988,3.191-23.019,5.753
c0.934,17.233,0.995,33.607-17.264,31.652c-5.686-6.537,3.063-16.076,0-28.774c-15.24-4.692-12.396,8.7-17.264,14.387
c-3.395-4.271-2.49-12.855-11.509-11.509c0,7.673,0,15.345,0,23.019c8.081,3.429,18.343,4.676,17.264,17.265
c-9.845-5.036-17.826,1.259-28.772,2.877c-0.647,5.439,3.242,6.348,2.876,11.509c-20.781,5.638-38.186-2.139-57.546-5.755
c8.283,14.739,31.661,14.379,37.406,31.652c-13.758,2.137-24.104-14.115-31.652-8.633c6.193,2.438,10.178,7.086,8.633,17.264
c-3.839,4.105-16.303,4.105-20.142,0c0.674,11.893,17.865,8.978,8.631,23.02c4.182,1.572,14.877-3.364,14.388,2.877
c-2.182,13.162-31.05-0.356-37.406,8.632c6.896,11.329,28.565,7.881,37.406,17.264c-1.878,14.427-12.533,20.074-25.897,23.02
c1.326,9.228,13.067,8.036,14.387,17.264c14.871,0.481,13.296-15.479,28.774-14.387c0.54,14.764-11.595,19.113,2.877,25.897
c-10.492,13.175-11.23,19.033-23.019,28.772c22.805,2.664,28.874-11.409,40.283-20.142c-2.058,7.814,13.571-2.061,11.509,5.755
c-4.952,7.767,3.175,22.35,5.755,31.65c7.086-14.639,24.575-52.949,43.159-28.772c2.435,10.239-8.327,17.241,2.878,20.14
c2.192-22.945,23.323-8.991,34.528-2.876c4.166-5.435,6.43-12.758,17.264-11.51c5.384,4.21,3.394,15.786,14.388,14.386
c3.618-14.832,3.551-27.433,14.387-28.772c4.794,3.839,0.961,16.303,5.753,20.142c16.855-0.546,24.453,8.159,31.652,17.264
c2.821-3.894,9.7-3.729,11.509-8.633c2.332-13.834-12.622-10.39-8.631-25.895c9.053-1.377,11.25,4.096,17.264,5.755
c4.94-10.819,8.486-8.065,14.387-14.388c23.979,18.039,41.816,11.808,71.934,17.264c-1.113-10.39-15.786-7.231-11.509-23.018
c-8.464-3.046-19.064-3.957-25.897-8.633c1.4-3.4,3.068-6.524,5.755-8.631c13.47,3.31,44.986,19.467,46.037-5.756
c-11.807,0.298-23.492,0.473-28.773-5.755c2.439-10.267,7.086-0.345,17.265-2.878c-9.649-13.283,1.758-10.46,2.877-25.895
c-6.166-9.521-26.475-2.203-31.652-5.756c9.24-13.779,34.226-11.812,43.161-25.896c-16.157-11.033-31.026-7.625-40.283,5.755
c-19.838-8.728,13.825-22.618,8.633-34.527c-14.173,4.068-22.277-8.931-40.283,0c-1.231-5.479-6.198-7.233-5.755-14.387
c1.288-8.303,12.381-6.804,14.386-14.387c-16.583-9.897-36.613,11.937-63.301,2.876c8.783-16.153,25.53-24.347,34.528-40.281
c-15.843,5.749-25.424,31.454-43.161,25.896c10.914-8.452,5.266-19.028,14.388-31.65c-17.888,18.046-29.702,12.679-51.794,17.264
c0.013-2.885-2.332-3.422-2.876-5.755c-1.933-10.729,11.671-20.717,5.754-25.896C532.046,477.715,525.325,485.381,510.292,484.735z
M631.14,510.632c14.477,0.96,28.762-13.325,23.019-23.02C649.742,498.537,634.281,498.427,631.14,510.632z M1028.215,527.896
c25.193,7.943,70.354,6.553,80.564-17.264C1089.977,513.287,1039.848,508.571,1028.215,527.896z M717.46,576.811
c9.773-4.619,26.661-2.113,31.651-11.509C737.562,568.133,719.702,564.66,717.46,576.811z M705.951,640.111
C728.937,657.017,720.579,623.069,705.951,640.111L705.951,640.111z M1056.987,651.621c1.242-6.434,14.185-1.166,20.142-2.877
C1071.016,638.734,1006.465,648.215,1056.987,651.621z M1005.195,697.658c3.08,7.52,25.159,3.198,37.406,0
C1032.368,694.931,1003.976,694.675,1005.195,697.658z M544.819,769.592c-5.058-0.693-6.558-4.95-5.755-11.509
c-19.191,0.495-6.963,14.534-20.142,20.142c15.348,0,30.695,0,46.038,0c0.989-12.499-2.175-20.844-11.51-23.02
C554.02,763.444,553.811,770.91,544.819,769.592z M593.734,781.103c10.633-1.839,28.667,3.726,34.528-2.878
c-10.676-3.709-10.682-18.09-25.895-17.264C605.396,773.579,592.638,770.41,593.734,781.103z M484.395,781.103
c9.594,0,19.187,0,28.774,0C511.691,769.374,485.497,769.412,484.395,781.103z"/>
<rect x="477.335" y="335.988" fill="#E33D27" width="60.604" height="58.978"/>
<rect x="346.712" y="365.477" fill="#E33D27" width="64.323" height="59.871"/>
<rect x="841.76" y="436.07" fill="#E33D27" width="55.402" height="80.423"/>
<rect x="490.15" y="254.548" fill="#E33D27" width="47.789" height="54.634"/>
<rect x="221.61" y="365.477" fill="#E33D27" width="37.53" height="50.935"/>
<g>
<path fill="#F37056" d="M960.874,342.508c-7.183,7.57-21.354,17.894-17.264,25.897c23.211-23.649,52.995-40.722,77.5-63.077
c-13.034,5.459-25.59,10.327-36.366,12.113C976.251,326.146,968.231,334.759,960.874,342.508z"/>
<path fill="#F37056" d="M982.291,286.56c2.111-6.42,4.772-12.605,11.396-17.626c-4.429,0.314-8.461,1.536-12.223,3.29
c-15.054,16.66-34.13,35.084-43.608,55.898C951.605,320.884,968.188,304.103,982.291,286.56z"/>
<path fill="#F37056" d="M1032.808,336.755c0.142,0.03,0.276,0.044,0.414,0.069c16.913-10.348,33.999-22.228,30.24-44.329
C1050.207,304.209,1039.396,318.372,1032.808,336.755z"/>
<path fill="#F37056" d="M1189.346,404.169c-9.241,0.124-17.092,0.667-24.393,0.958c-3.92,4.524-6.771,9.897-8.097,16.427
C1169.379,415.4,1184.175,412.447,1189.346,404.169z"/>
<path fill="#F37056" d="M1093.542,331.732c-5.376,1.275-10.857,2.256-16.521,2.836c-2.233,6.923-5.04,13.786-12.562,19.45
C1075.991,350.17,1084.845,340.787,1093.542,331.732z"/>
<path fill="#F37056" d="M929.224,408.688c7.288-8.133,29.083-16.855,23.02-28.774C945.354,388.439,924.413,398.027,929.224,408.688
z"/>
<path fill="#F37056" d="M503.376,448.97c-4.265-2.443-6.188-7.237-5.755-14.386C477.616,434.775,501.662,454.479,503.376,448.97z"
/>
<path fill="#F37056" d="M759.46,307.98c12.773-7.604,29.892-34.197,17.264-48.915C772.392,276.796,765.091,291.553,759.46,307.98z"
/>
<path fill="#F37056" d="M890.099,290.81c0.45,0.896,1.015,1.823,1.72,2.784c1.44-3.468,5.58-7.331,9.607-11.299
C897.672,285.156,893.89,287.984,890.099,290.81z"/>
<path fill="#F37056" d="M863.046,397.178c4.893-7.058,12.008-14.521,18.729-22.142c1.233-1.57,2.54-3.068,3.899-4.512
c7.834-9.309,14.325-18.791,14.776-28.016C885.063,355.918,868.411,383.337,863.046,397.178z"/>
<path fill="#F37056" d="M1048.356,202.755c-2.375-5.043-5.084-8.048-8.039-9.602c-6.688,7.37-15.63,14.047-21.896,16.997
c-2.716,4.204-5.642,8.197-8.64,12.116C1022.446,215.568,1035.576,209.336,1048.356,202.755z"/>
<path fill="#F37056" d="M900.451,236.047c4.218-4.366,8.189-8.975,12.015-13.735c-4.415-1.273-6.41-3.791-10.855,0.584
c-0.362,0.545-0.758,1.11-1.132,1.661C900.215,228.505,900.145,232.372,900.451,236.047z"/>
<path fill="#F37056" d="M609.837,420.197c6.396-9.205,0.152-25.672-8.631-28.773C592.226,403.22,606.78,411.374,609.837,420.197z"
/>
<path fill="#F37056" d="M1194.9,524.134c-7.083,1.752-15.417,2.252-21.102,5.402c-0.141,1.167,0.173,1.88,0.733,2.349
C1182.579,530.562,1193.381,531.989,1194.9,524.134z"/>
<path fill="#F37056" d="M1139.644,437.292c2.543-5.611,6.859-9.652,11.949-12.835c-14.169,4.826-22.213,15.774-38.219,18.758
C1121.475,443.252,1130.327,440.713,1139.644,437.292z"/>
<path fill="#F37056" d="M1127.288,506.742c-1.045,0.868-1.879,1.754-2.405,2.652c2.51,1.021,5.441,1.441,8.66,1.458
C1131.681,509.263,1128.91,508.577,1127.288,506.742z"/>
<path fill="#F37056" d="M1047.196,382.792c5.236-1.121,9.68-3.037,13.516-5.561c0.651-2.398,1.516-4.628,2.575-6.71
C1056.552,373.24,1051.367,377.512,1047.196,382.792z"/>
<path fill="#F37056" d="M978.138,417.319c27.257-1.815,43.566-28.924,63.303-28.772c-5.726-10.976,16.68-14.905,8.631-25.897
C1030.297,385.073,996.555,393.537,978.138,417.319z"/>
<path fill="#F37056" d="M957.997,509.395c-4.4,8.846,18.792,8.846,14.388,0c-0.067-0.618-0.256-1.104-0.495-1.534
c-0.405-0.039-0.817-0.064-1.223-0.106c0.352-0.057,0.709-0.121,1.062-0.181C969.09,503.774,959.548,507.923,957.997,509.395z"/>
<path fill="#F37056" d="M1174.96,568.179c-11.15-6.416-27.655-5.69-44.926-3.878c-2.112,1.585-3.874,3.4-5.151,5.519
c12.32,3.887,29.403,5.526,44.851,3.417C1171.755,571.834,1173.537,570.185,1174.96,568.179z"/>
<path fill="#F37056" d="M1078.151,550.431c16.431-5.851,37.288-4.484,58.229-4.133c9.858-1.38,19.687-2.915,29.369-4.328
c-0.368-3.449,0.435-5.734,1.99-7.261c-33.084-3.223-68.665,9.885-100.404,14.969
C1070.905,550.046,1074.514,550.288,1078.151,550.431z"/>
<path fill="#F37056" d="M519.384,275.245c-5.662-14.417-13.493-28.914-22.875-40.615c-0.964,3.086-1.932,6.056-2.847,8.863
c1.231,0.242,2.518,0.587,3.958,1.187c14.932,25.513,12.746,62.474,31.652,77.687c0.477-8.462-1.174-19.539-4.568-31.442
c-0.057,3.267-0.203,6.626-0.026,9.66c-11.858,0.762-14.358-18.07-8.631-25.896C517.35,274.683,518.437,274.894,519.384,275.245z"
/>
<path fill="#F37056" d="M267.434,218.783c1.495-0.619,2.919-1.093,4.31-1.493c-11.518-10.683-24.522-19.877-40.555-26.044
c0.562,4.085,2.214,7.972,4.381,11.664C249.279,196.5,264.522,208.122,267.434,218.783z"/>
<path fill="#F37056" d="M208.169,401.292c-6.071-1.665-5.877,2.939-7.165,6.057c28.852,14.916,58.187,30.438,92.325,44.498
c7.57,0.854,2.265-11.161,11.509-8.632c-11.596-15.786-28.231-26.537-45.874-36.275c-9.229-0.704-15.755-4.112-19.403-10.394
c-23.185-12.392-45.614-25.54-58.449-48.283c55.423,11.464,96.746,35.034,138.113,48.914
c-16.806-24.092-58.581-43.732-91.072-63.115c0.056,0.345,0.123,0.682,0.157,1.05c-7.8-2.748-19.838-1.262-17.264-14.387
c4.555,1.734,9.483,3.094,12.92,5.942c17.211-2.379,43.146,13.536,60.73,27.35c17.062,0.757,22.497-4.75,28.774,5.754
c3.467-3.249,5.214-8.21,14.386-5.754c-2.416-17.22-41.047-27.381-34.528-34.529c-2.821-5.754-23.592,3.17-17.264-5.754
c17.022-8.621,52.714,19.045,71.935,34.528c8.856,2.146,5.53-7.896,14.386-5.755c-17.479-41.024-62.903-54.107-94.953-80.565
c16.1-2.625,34.86,16.897,48.915,25.896c-10.372-23.648-40.91-41.933-64.713-63.33c1.58,2.518,2.603,4.867,2.571,7.02
c-41.592-1.626-41.817-71.881-83.443-54.67c-3.102-11.36-20.198-23.813-34.529-14.387c22.598,31.125,69.99,52.771,83.443,83.443
c-14.055-9-32.814-28.521-48.915-25.896c32.05,26.456,77.475,39.538,94.952,80.565c-8.856-2.143-5.53,7.898-14.386,5.755
c-19.22-15.482-54.912-43.15-71.934-34.528c-6.329,8.921,14.442,0,17.264,5.753c-6.519,7.146,32.111,17.307,34.528,34.528
c-9.172-2.458-10.919,2.506-14.387,5.755c-6.278-10.506-11.712-5-28.773-5.755c-19.551-15.362-49.46-33.396-66.179-25.896
c33.325,21.353,82.185,42.5,100.707,69.056c-41.368-13.88-82.69-37.453-138.113-48.915
C110.744,352.937,177.305,359.27,208.169,401.292z"/>
<path fill="#F37056" d="M309.93,240.203c3.794,5.699,7.626,11.627,11.979,16.89c1.75,1.079,3.316,2.125,4.232,3.209
c1.371,1.622,2.664,3.302,3.917,5.013c5.709,4.648,12.412,7.81,20.818,8.138c0.135-9.784-20.697-23.373-23.019-40.283
c5.356,2.061,10.369,4.466,15.109,7.143c-3.299-4.795-6.03-13.607-5.317-20.292c11.616-0.107,2.53,20.492,11.51,23.019
c-0.256,0.247-0.529,0.405-0.802,0.529c40.576,25.857,60.456,72.41,100.348,98.942c-9.693-14.363-15.999-28.583-25.895-40.283
c-2.907-3.433-12.078-6.451-14.388-11.509c-5.18-11.346,2.502-24.227,0-37.406c-3.431-18.093-13.198-33.747-24.575-49.033
c-0.958,0.433-1.958,0.885-3.037,1.354c-5.465-8.079-10.4-16.69-15.39-25.247c-6.822-8.953-13.355-18.146-18.698-27.976
c7.436,25.506,24.83,41.049,31.21,67.609c-7.756-5.673-13.762-13.092-17.264-23.019c-56.71-24.946-60.425-88.582-120.849-112.217
c12.285,49.581,63.099,80.007,71.934,126.604C313.643,221.337,309.731,231.121,309.93,240.203z M320.386,191.246
c7.801-5.695,15.697,7.736,17.264,17.264C327.535,213.503,319.386,205.354,320.386,191.246z"/>
<path fill="#F37056" d="M390.342,171.301c18.823,25.289,33.874,53.051,66.997,67.624c3.5,9.93,9.508,17.348,17.264,23.019
c-6.502-27.065-24.469-42.667-31.652-69.057c13.106,16.628,22.53,36.938,34.529,54.669c1.955-0.851,3.672-1.661,5.28-2.349
c-7.824-18.554-2.404-55.13,6.276-69.523c-5.993-14.727-12.288-30.299-15.581-45.543c-3.897-6.521-9.289-10.278-17.834-7.952
c-1.001,14.612,24.4,54.842,5.753,77.689c-28.446-51.154-46.88-112.335-80.565-158.254
c-22.962,42.564,23.513,102.04,25.896,138.113C402.079,178.449,395.608,171.753,390.342,171.301z"/>
<path fill="#F37056" d="M307.717,362.65c-2.574,13.127,9.463,11.639,17.264,14.386C324.087,367.382,315.359,365.561,307.717,362.65
z"/>
<path fill="#F37056" d="M422.181,231.992c2.706,6.736,4.949,13.468,6.649,19.912c1.728-0.054,3.573-0.523,5.49-1.47
C433.1,243.018,428.039,233.279,422.181,231.992z"/>
<path fill="#F37056" d="M445.829,284.961c-8.981-2.523,0.107-23.125-11.509-23.018
C433.156,272.845,441.148,289.458,445.829,284.961z"/>
<path fill="#F37056" d="M258.801,736.706c-4.395,0.452-8.885,0.662-13.462,0.742c1.256,0.752,2.302,1.819,3.113,3.371
c-5.159,5.39-17.657,3.44-20.142,11.509c12.687,6.804,20.833-3.199,28.999-9.835C257.897,740.678,258.528,738.765,258.801,736.706z
"/>
<path fill="#F37056" d="M266.762,755.276c0.264,0.874,0.81,1.79,1.832,2.807c3.484-0.483,6.612-1.317,9.545-2.352
C274.396,755.826,270.598,755.697,266.762,755.276z"/>
<path fill="#F37056" d="M87.321,398.415c0.697-5.061,4.951-6.556,11.509-5.755c-9.717,9.203,1.383,16.893,11.509,8.633
c-0.995,12.268,20.484,25.031,28.774,37.406c-4.737,4.849-6.25,12.93-11.51,17.263c-13.684-7.414-34.494-7.701-51.792-11.509
c25.82,35.04,96.11,25.613,134.24,48.339c5.202,1.239,10.045,2.832,14.222,5.095c5.26-4.334,6.771-12.415,11.509-17.264
c-8.289-12.375-29.768-25.138-28.773-37.406c-10.127,8.261-21.226,0.574-11.509-8.632c-6.559-0.797-10.813,0.698-11.51,5.755
c-11.38-14.19-41.547-24.576-69.056-37.406c12.836-21.153,44.149,17.963,57.867-3.383c-33.871-15.463-63.552-32.002-94.112-47.173
c-11.909,32.229-46.712-13.968-60.424,8.632C45.773,373.837,75.941,384.222,87.321,398.415z"/>
<path fill="#F37056" d="M558.045,241.802c18.647-22.845-6.755-63.077-5.755-77.688c16.821-4.578,21.438,14.355,26.444,31.704
c3.859-55.909,10.377-113.72-16.651-151.317c-31.825,10.377-27.278,57.123-43.161,83.443c-7.396-21.926-3.011-65.862-14.387-74.811
c-2.882,0.008-3.421-2.33-5.755-2.878c-8.584,14.876-7.112,36.892-4.959,58.59C517.875,150.519,534.557,199.568,558.045,241.802z
M547.697,127.944c8.013,10.453,0.078,50.795,2.877,74.811C529.809,185.218,546.247,154.523,547.697,127.944z"/>
<path fill="#F37056" d="M345.122,753.97c-6.598-6.066-16.163-5.833-27.619-3.981c1.346,3.273,4.917,4.318,5.761,8.095
c-5.923,3.67-14.595,4.592-14.387,14.387c5.249-0.438,10.112-2.163,14.741-4.403C329.979,762.56,338.159,758.873,345.122,753.97z"
/>
<path fill="#F37056" d="M248.452,712.046c-0.542,0.382-1.118,0.733-1.677,1.101c11.644,3.148,23.822,5.156,29.29-2.338
c-32.949-14.757-71.948-23.459-106.184-36.933c-11.934,1.41-29.524-6.348-39.401-7.868c-0.224,23.752-36.545,11.409-57.547,14.387
c0.922,6.672-0.461,11.046-2.877,14.388c35.505-2.806,65.364,2.744,92.075,0c-0.888,6.726-5.632,11.888,0,17.264
C198.2,720.197,232.262,697.155,248.452,712.046z"/>
<path fill="#F37056" d="M93.076,519.263c23.631,8.046,46.756,13.755,74.811,23.02c-17.04,2.574-40.098-3.917-48.915,0
c18.857,8.913,50.641,4.909,70.734,12.585c0.714-6.782,4.347-10.647,11.549-10.944c-27.892-14.313-72.805-11.594-92.075-34.528
c67.275,12.082,131.448,13.792,198.538,25.896c-37.479-23.228-107.606-13.814-134.334-47.8
c-53.725-7.24-106.279-10.213-160.873-20.021c19.271,22.936,64.184,20.216,92.075,34.528
C95.375,502.381,91.929,508.523,93.076,519.263z"/>
<path fill="#F37056" d="M47.038,619.971c33.711,18.32,76.542,27.512,114.439,41.641c38.881-0.242,71.881,1.775,105.957-2.594
c-14.836-7.222-29.162-14.954-51.792-14.387c-1.996-9.515-8.026-14.989-14.387-20.142c14.393,0.546,26.632,3.118,37.405-11.511
c-28.683-5.918-66.628-11.896-103.584-17.264c-0.488-8.159,9.733-5.614,5.755-17.264c44.334,1.663,97.285,27.155,149.622,20.141
c-19.612-10.115-54.624-4.844-74.81-14.386c8.817-3.917,31.875,2.574,48.914,0c-28.054-9.262-51.179-14.971-74.811-23.02
c-0.152-1.431-0.21-2.767-0.196-4.032c-50.952,5.159-102.247-19.012-145.388-20.627c3.979,11.649-6.243,9.102-5.754,17.264
c36.956,5.367,74.9,11.347,103.584,17.264c-10.773,14.626-23.013,12.055-37.406,11.511c6.362,5.149,12.392,10.627,14.387,20.142
c22.631-0.57,36.957,7.162,51.792,14.387C131.616,622.109,93.896,618.7,47.038,619.971z"/>
<path fill="#F37056" d="M1083.058,351.613c23.241-13.143,56.156-17.439,63.128-36.642c-15.511,4.544-29.56,10.265-43.976,14.46
C1095.478,334.435,1089.207,340.808,1083.058,351.613z"/>
<path fill="#F37056" d="M503.376,221.66c-0.172-2.607-0.598-5.354-1.188-8.191c-0.486,2.327-1.028,4.651-1.613,6.958
C501.561,220.979,502.502,221.418,503.376,221.66z"/>
<path fill="#F37056" d="M333.613,431.706c2.473,10.96,10.272,16.589,23.018,17.264C355.67,436.506,340.699,438.051,333.613,431.706
z"/>
<path fill="#F37056" d="M457.339,322.367c2.882,10.638,11.565,30.522,20.142,25.897
C469.118,341.283,466.702,328.352,457.339,322.367z"/>
<path fill="#F37056" d="M612.715,316.613c-5.726,7.828-3.226,26.66,8.633,25.895C620.713,331.634,624.276,316.567,612.715,316.613z
"/>
<path fill="#F37056" d="M675.856,231.276c1.558-4.553,2.999-9.222,4.199-14.134c8.91,10.386,3.006,26.675-5.728,38.041
c-1.132,21.552-1.289,42.471,1.689,61.431c16.882-26.089,6.238-92.453,8.631-123.727c12.837,6.35,2.355,36.018,5.755,51.793
c9.998-29.156,17.747-76.622,8.632-100.708c31.207-12.892,6.733-68.573,40.283-74.812c1.399,3.519,2.481,7.109,3.336,10.751
c4.207-11.24,7.807-22.055,9.335-32.533c1.185-8.138,5.844-22.544-5.755-28.774c-21.946,23.131-22.936,67.216-40.283,94.952
c-14.696-1.781-23.28,6.128-29.863,17.402C681.301,161.274,678.35,196.469,675.856,231.276z"/>
<path fill="#F37056" d="M579.348,274.688c-1.434-9.114-2.142-18.679-2.366-28.551c-3.036,20.503-1.369,43.75,9.838,50.334
c6.732-22.834,27.025-70.625,2.876-89.199c5.542-13.125,3.13-33.365,1.032-54.141c-0.779-0.859-1.652-1.627-2.747-2.169
C585.586,182.237,596.23,248.598,579.348,274.688z"/>
<path fill="#F37056" d="M642.368,184.844c-4.242,22.451-12.071,45.527,4.875,59.835c-2.124-18.231,1.93-45.861,0.506-62.69
c-1.584,1.338-3.273,2.521-5.099,3.502C642.546,185.28,642.469,185.058,642.368,184.844z"/>
<path fill="#F37056" d="M735.584,171.567c-3.144,20.468-4.104,39.732,3.734,55.847c28.184-15.123,24.885-76.587,63.302-71.934
c1.431-2.284,2.714-4.715,3.945-7.202c-0.443-9.034-3.183-16.45-11.417-20.335c17.382-20.041,34.624-55.513,31.652-86.321
c-9.649,3.774-13.927,12.925-23.02,17.264c-9.778,43.213-40.334,65.083-63.303,97.83
C737.782,160.567,737.619,166.937,735.584,171.567z"/>
<path fill="#F37056" d="M615.593,169.868c13.074-21.664,12.321-57.153,29.395-74.822c3.894-23.297,6.041-46.757-2.338-67.809
c-32.509,6.044-10.543,58.502-37.533,73.487C611.578,115.878,609.23,151.007,615.593,169.868z"/>
<path fill="#F37056" d="M989.466,132.274c-6.629,20.231-17.129,36.588-25.714,54.857c19.602,34.371-25.643,69.833-37.405,100.708
c8.093-4.883,15.348-10.604,22.084-16.849c5.897-8.486,12.911-15.855,20.705-22.443c7.69-9.467,14.92-19.396,22.237-29.24
c-6.167,3.535-12.203,5.396-17.828,3.588c2.141-21.838,30.402-17.553,37.405-34.528c-5.158-10.793-15.994,1.975-23.019-5.755
c4.613-24.188,44.166-28.692,40.283-51.792c-12.752,5.465-18.552,17.894-34.528,20.142
C993.687,143.325,992.877,136.5,989.466,132.274z"/>
<path fill="#F37056" d="M913.12,153.84c-5.465,6.44-10.646,13.165-15.746,19.968c4.431,4.585,5.854,11.127,5.926,18.638
c6.564-7.66,12.868-15.579,18.452-24.219c13.358-6.291,38.896-29.535,28.774-40.283C935.453,122.529,928.643,150.125,913.12,153.84
z"/>
<path fill="#F37056" d="M822.007,172.346c-3.472,14.691-4.96,30.12-2.122,46.437c16.079,3.051,12.233-12.965,17.264-20.142
c10.699-15.258,23.033-28.164,34.16-41.958c-0.713-3.833-2.051-7.663-4.227-11.476c12.263-26.102,28.465-48.266,31.651-83.443
c-13.611-8.084-16.202,7.488-25.896,11.51c3.957,9.104,0.631,9.615,0,20.142C855.191,119.025,840.405,147.489,822.007,172.346z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -0,0 +1,9 @@
span.caption {
font-size: .8em;
font-weight: 600;
}
span.caption code {
font-size: 0.875em;
font-weight: 400;
}

View File

@ -236,14 +236,14 @@ method, which are repeated here in Listing 11-5. Lets put this code in the
```rust
# fn main() {}
#[derive(Debug)]
pub struct Rectangle {
length: u32,
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
pub fn can_hold(&self, other: &Rectangle) -> bool {
self.length > other.length && self.width > other.width
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
```
@ -253,9 +253,9 @@ impl Rectangle {
The `can_hold` method returns a Boolean, which means its a perfect use case
for the `assert!` macro. In Listing 11-6, we write a test that exercises the
`can_hold` method by creating a `Rectangle` instance that has a length of 8 and
a width of 7 and asserting that it can hold another `Rectangle` instance that
has a length of 5 and a width of 1.
`can_hold` method by creating a `Rectangle` instance that has a width of 8 and
a height of 7 and asserting that it can hold another `Rectangle` instance that
has a width of 5 and a height of 1.
<span class="filename">Filename: src/lib.rs</span>
@ -267,8 +267,8 @@ mod tests {
#[test]
fn larger_can_hold_smaller() {
let larger = Rectangle { length: 8, width: 7 };
let smaller = Rectangle { length: 5, width: 1 };
let larger = Rectangle { width: 8, height: 7 };
let smaller = Rectangle { width: 5, height: 1 };
assert!(larger.can_hold(&smaller));
}
@ -315,8 +315,8 @@ mod tests {
#[test]
fn smaller_cannot_hold_larger() {
let larger = Rectangle { length: 8, width: 7 };
let smaller = Rectangle { length: 5, width: 1 };
let larger = Rectangle { width: 8, height: 7 };
let smaller = Rectangle { width: 5, height: 1 };
assert!(!smaller.can_hold(&larger));
}
@ -338,20 +338,20 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Two tests that pass! Now lets see what happens to our test results when we
introduce a bug in our code. Lets change the implementation of the `can_hold`
method by replacing the greater than sign with a less than sign when it
compares the lengths:
compares the widths:
```rust
# fn main() {}
# #[derive(Debug)]
# pub struct Rectangle {
# length: u32,
# struct Rectangle {
# width: u32,
# height: u32,
# }
// --snip--
impl Rectangle {
pub fn can_hold(&self, other: &Rectangle) -> bool {
self.length < other.length && self.width > other.width
fn can_hold(&self, other: &Rectangle) -> bool {
self.width < other.width && self.height > other.height
}
}
```
@ -376,8 +376,8 @@ failures:
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
```
Our tests caught the bug! Because `larger.length` is 8 and `smaller.length` is
5, the comparison of the lengths in `can_hold` now returns `false`: 8 is not
Our tests caught the bug! Because `larger.width` is 8 and `smaller.width` is
5, the comparison of the widths in `can_hold` now returns `false`: 8 is not
less than 5.
### Testing Equality with the `assert_eq!` and `assert_ne!` Macros

View File

@ -59,7 +59,7 @@ The error tells us we cant call `join` because we only have a mutable borrow
of each `worker` and `join` takes ownership of its argument. To solve this
issue, we need to move the thread out of the `Worker` instance that owns
`thread` so `join` can consume the thread. We did this in Listing 17-15: if
`Worker` holds an `Option<thread::JoinHandle<()>` instead, we can call the
`Worker` holds an `Option<thread::JoinHandle<()>>` instead, we can call the
`take` method on the `Option` to move the value out of the `Some` variant and
leave a `None` variant in its place. In other words, a `Worker` that is running
will have a `Some` variant in `thread`, and when we want to clean up a

Some files were not shown because too many files have changed in this diff Show More