diff --git a/.travis.yml b/.travis.yml index ec8060b9f56aa..990cac4dbe98b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -197,23 +197,10 @@ matrix: . src/ci/docker/x86_64-gnu-tools/repo.sh; commit_toolstate_change "$MESSAGE_FILE" "$TRAVIS_BUILD_DIR/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "$MESSAGE_FILE" "$TOOLSTATE_REPO_ACCESS_TOKEN"; -env: - global: - - SCCACHE_BUCKET=rust-lang-ci-sccache2 - - SCCACHE_REGION=us-west-1 - - AWS_ACCESS_KEY_ID=AKIAJAMV3QAMMA6AXHFQ - # AWS_SECRET_ACCESS_KEY=... - - secure: "j96XxTVOSUf4s4r4htIxn/fvIa5DWbMgLqWl7r8z2QfgUwscmkMXAwXuFNc7s7bGTpV/+CgDiMFFM6BAFLGKutytIF6oA02s9b+usQYnM0th7YQ2AIgm9GtMTJCJp4AoyfFmh8F2faUICBZlfVLUJ34udHEe35vOklix+0k4WDo=" - # TOOLSTATE_REPO_ACCESS_TOKEN=... - - secure: "ESfcXqv4N2VMhqi2iIyw6da9VrsA78I4iR1asouCaq4hzTTrkB4WNRrfURy6xg72gQ4nMhtRJbB0/2jmc9Cu1+g2CzXtyiL223aJ5CKrXdcvbitopQSDfp07dMWm+UED+hNFEanpErKAeU/6FM3A+J+60PMk8MCF1h9tqNRISJw=" - before_install: - # We'll use the AWS cli to download/upload cached docker layers, so install - # that here. - - if [ "$TRAVIS_OS_NAME" = linux ]; then - pip install --user awscli; - export PATH=$PATH:$HOME/.local/bin; - fi + # We'll use the AWS cli to download/upload cached docker layers as well as + # push our deployments, so download that here. + - pip install --user awscli; export PATH=$PATH:$HOME/.local/bin - mkdir -p $HOME/rustsrc # FIXME(#46924): these two commands are required to enable IPv6, # they shouldn't exist, please revert once more official solutions appeared. @@ -276,6 +263,23 @@ after_success: echo "#### Build successful; Disk usage after running script:"; df -h; du . | sort -nr | head -n100 + - > + if [ "$DEPLOY$DEPLOY_ALT" == "1" ]; then + mkdir -p deploy/$TRAVIS_COMMIT; + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + rm -rf build/dist/doc && + cp -r build/dist/* deploy/$TRAVIS_COMMIT; + else + rm -rf obj/build/dist/doc && + cp -r obj/build/dist/* deploy/$TRAVIS_COMMIT; + fi; + ls -la deploy/$TRAVIS_COMMIT; + deploy_dir=rustc-builds; + if [ "$DEPLOY_ALT" == "1" ]; then + deploy_dir=rustc-builds-alt; + fi; + travis_retry aws s3 cp --no-progress --recursive --acl public-read ./deploy s3://rust-lang-ci2/$deploy_dir + fi after_failure: - > @@ -322,77 +326,3 @@ after_failure: notifications: email: false - -before_deploy: - - mkdir -p deploy/$TRAVIS_COMMIT - - > - if [ "$TRAVIS_OS_NAME" == "osx" ]; then - rm -rf build/dist/doc && - cp -r build/dist/* deploy/$TRAVIS_COMMIT; - else - rm -rf obj/build/dist/doc && - cp -r obj/build/dist/* deploy/$TRAVIS_COMMIT; - fi - - ls -la deploy/$TRAVIS_COMMIT - -deploy: - - provider: s3 - bucket: rust-lang-ci2 - skip_cleanup: true - local_dir: deploy - upload_dir: rustc-builds - acl: public_read - region: us-west-1 - access_key_id: AKIAJVBODR3IA4O72THQ - secret_access_key: - secure: "kUGd3t7JcVWFESgIlzvsM8viZgCA9Encs3creW0xLJaLSeI1iVjlJK4h/2/nO6y224AFrh/GUfsNr4/4AlxPuYb8OU5oC5Lv+Ff2JiRDYtuNpyQSKAQp+bRYytWMtrmhja91h118Mbm90cUfcLPwkdiINgJNTXhPKg5Cqu3VYn0=" - on: - branch: auto - condition: $DEPLOY = 1 - - # this is the same as the above deployment provider except that it uploads to - # a slightly different directory and has a different trigger - - provider: s3 - bucket: rust-lang-ci2 - skip_cleanup: true - local_dir: deploy - upload_dir: rustc-builds-alt - acl: public_read - region: us-west-1 - access_key_id: AKIAJVBODR3IA4O72THQ - secret_access_key: - secure: "kUGd3t7JcVWFESgIlzvsM8viZgCA9Encs3creW0xLJaLSeI1iVjlJK4h/2/nO6y224AFrh/GUfsNr4/4AlxPuYb8OU5oC5Lv+Ff2JiRDYtuNpyQSKAQp+bRYytWMtrmhja91h118Mbm90cUfcLPwkdiINgJNTXhPKg5Cqu3VYn0=" - on: - branch: auto - condition: $DEPLOY_ALT = 1 - - # These two providers are the same as the two above, except deploy on the - # try branch. Travis does not appear to provide a way to use "or" in these - # conditions. - - provider: s3 - bucket: rust-lang-ci2 - skip_cleanup: true - local_dir: deploy - upload_dir: rustc-builds - acl: public_read - region: us-west-1 - access_key_id: AKIAJVBODR3IA4O72THQ - secret_access_key: - secure: "kUGd3t7JcVWFESgIlzvsM8viZgCA9Encs3creW0xLJaLSeI1iVjlJK4h/2/nO6y224AFrh/GUfsNr4/4AlxPuYb8OU5oC5Lv+Ff2JiRDYtuNpyQSKAQp+bRYytWMtrmhja91h118Mbm90cUfcLPwkdiINgJNTXhPKg5Cqu3VYn0=" - on: - branch: try - condition: $DEPLOY = 1 - - - provider: s3 - bucket: rust-lang-ci2 - skip_cleanup: true - local_dir: deploy - upload_dir: rustc-builds-alt - acl: public_read - region: us-west-1 - access_key_id: AKIAJVBODR3IA4O72THQ - secret_access_key: - secure: "kUGd3t7JcVWFESgIlzvsM8viZgCA9Encs3creW0xLJaLSeI1iVjlJK4h/2/nO6y224AFrh/GUfsNr4/4AlxPuYb8OU5oC5Lv+Ff2JiRDYtuNpyQSKAQp+bRYytWMtrmhja91h118Mbm90cUfcLPwkdiINgJNTXhPKg5Cqu3VYn0=" - on: - branch: try - condition: $DEPLOY_ALT = 1 diff --git a/appveyor.yml b/appveyor.yml index 04951454c29e1..d519993f14288 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,12 +1,5 @@ environment: - SCCACHE_BUCKET: rust-lang-ci-sccache2 - SCCACHE_REGION: us-west-1 - AWS_ACCESS_KEY_ID: AKIAJAMV3QAMMA6AXHFQ - AWS_SECRET_ACCESS_KEY: - secure: 7Y+JiquYedOAgnUU26uL0DPzrxmTtR+qIwG6rNKSuWDffqU3vVZxbGXim9QpTO80 SCCACHE_DIGEST: f808afabb4a4eb1d7112bcb3fa6be03b61e93412890c88e177c667eb37f46353d7ec294e559b16f9f4b5e894f2185fe7670a0df15fd064889ecbd80f0c34166c - TOOLSTATE_REPO_ACCESS_TOKEN: - secure: gKGlVktr7iuqCoYSxHxDE9ltLOKU0nYDEuQxvWbNxUIW7ri5ppn8L06jQzN0GGzN # By default schannel checks revocation of certificates unlike some other SSL # backends, but we've historically had problems on CI where a revocation @@ -235,10 +228,8 @@ before_deploy: deploy: - provider: S3 - skip_cleanup: true - access_key_id: AKIAJVBODR3IA4O72THQ - secret_access_key: - secure: tQWIE+DJHjXaV4np/3YeETkEmXngtIuIgAO/LYKQaUshGLgN8cBCFGG3cHx5lKLt + access_key_id: $(AWS_ACCESS_KEY_ID) + secret_access_key: $(AWS_SECRET_ACCESS_KEY) bucket: rust-lang-ci2 set_public: true region: us-west-1 @@ -252,10 +243,8 @@ deploy: # This provider is the same as the one above except that it has a slightly # different upload directory and a slightly different trigger - provider: S3 - skip_cleanup: true - access_key_id: AKIAJVBODR3IA4O72THQ - secret_access_key: - secure: tQWIE+DJHjXaV4np/3YeETkEmXngtIuIgAO/LYKQaUshGLgN8cBCFGG3cHx5lKLt + access_key_id: $(AWS_ACCESS_KEY_ID) + secret_access_key: $(AWS_SECRET_ACCESS_KEY) bucket: rust-lang-ci2 set_public: true region: us-west-1 diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 71a89cd6d76b4..ab2c7c2325c99 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -130,7 +130,7 @@ impl PathSet { fn has(&self, needle: &Path) -> bool { match self { PathSet::Set(set) => set.iter().any(|p| p.ends_with(needle)), - PathSet::Suite(_) => false, + PathSet::Suite(suite) => suite.ends_with(needle), } } @@ -1844,7 +1844,7 @@ mod __test { ); // Ensure we don't build any compiler artifacts. - assert!(builder.cache.all::().is_empty()); + assert!(!builder.cache.contains::()); assert_eq!( first(builder.cache.all::()), &[test::Crate { @@ -1856,4 +1856,34 @@ mod __test { },] ); } + + #[test] + fn test_exclude() { + let mut config = configure(&[], &[]); + config.exclude = vec![ + "src/test/run-pass".into(), + "src/tools/tidy".into(), + ]; + config.cmd = Subcommand::Test { + paths: Vec::new(), + test_args: Vec::new(), + rustc_args: Vec::new(), + fail_fast: true, + doc_tests: DocTests::No, + bless: false, + compare_mode: None, + }; + + let build = Build::new(config); + let builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); + + // Ensure we have really excluded run-pass & tidy + assert!(!builder.cache.contains::()); + assert!(!builder.cache.contains::()); + + // Ensure other tests are not affected. + assert!(builder.cache.contains::()); + assert!(builder.cache.contains::()); + } } diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs index fd9a1be207280..0b561a3523f2b 100644 --- a/src/bootstrap/cache.rs +++ b/src/bootstrap/cache.rs @@ -286,4 +286,9 @@ impl Cache { v.sort_by_key(|&(a, _)| a); v } + + #[cfg(test)] + pub fn contains(&self) -> bool { + self.0.borrow().contains_key(&TypeId::of::()) + } } diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index bcf2f6a675e02..862fbbf1f286b 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -85,7 +85,12 @@ check-stage2-T-arm-linux-androideabi-H-x86_64-unknown-linux-gnu: check-stage2-T-x86_64-unknown-linux-musl-H-x86_64-unknown-linux-gnu: $(Q)$(BOOTSTRAP) test --target x86_64-unknown-linux-musl -TESTS_IN_2 := src/test/run-pass src/test/compile-fail src/test/run-pass-fulldeps +TESTS_IN_2 := \ + src/test/ui \ + src/test/run-pass \ + src/test/compile-fail \ + src/test/run-pass-fulldeps \ + src/tools/linkchecker appveyor-subset-1: $(Q)$(BOOTSTRAP) test $(TESTS_IN_2:%=--exclude %) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 96d04253cc485..9ccfecd46fdb2 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -29,7 +29,8 @@ use rustc::hir; declare_lint! { pub UNUSED_MUST_USE, Warn, - "unused result of a type flagged as #[must_use]" + "unused result of a type flagged as #[must_use]", + report_in_external_macro: true } declare_lint! { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index a8907674a0890..285025bed4af4 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -36,7 +36,6 @@ use syntax_pos::{MultiSpan, Span}; use std::cell::{Cell, RefCell}; use std::collections::BTreeMap; -use std::fmt::Write; use std::{mem, ptr}; /// Contains data for specific types of import directives. @@ -778,17 +777,14 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let msg = format!("`{}` import is ambiguous", name); let mut err = self.session.struct_span_err(span, &msg); - let mut suggestion_choices = String::new(); + let mut suggestion_choices = vec![]; if external_crate.is_some() { - write!(suggestion_choices, "`::{}`", name); + suggestion_choices.push(format!("`::{}`", name)); err.span_label(span, format!("can refer to external crate `::{}`", name)); } if let Some(result) = results.module_scope { - if !suggestion_choices.is_empty() { - suggestion_choices.push_str(" or "); - } - write!(suggestion_choices, "`self::{}`", name); + suggestion_choices.push(format!("`self::{}`", name)); if uniform_paths_feature { err.span_label(result.span, format!("can refer to `self::{}`", name)); @@ -801,7 +797,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { err.span_label(result.span, format!("shadowed by block-scoped `{}`", name)); } - err.help(&format!("write {} explicitly instead", suggestion_choices)); + err.help(&format!("write {} explicitly instead", suggestion_choices.join(" or "))); if uniform_paths_feature { err.note("relative `use` paths enabled by `#![feature(uniform_paths)]`"); } else { diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 77f125f3c5b56..3d5920dfb69ac 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -141,6 +141,10 @@ impl Command { pub fn get_argv(&self) -> &Vec<*const c_char> { &self.argv.0 } + #[cfg(not(target_os = "fuchsia"))] + pub fn get_program(&self) -> &CString { + return &self.program; + } #[allow(dead_code)] pub fn get_cwd(&self) -> &Option { @@ -244,6 +248,10 @@ impl CStringArray { pub fn as_ptr(&self) -> *const *const c_char { self.ptrs.as_ptr() } + #[cfg(not(target_os = "fuchsia"))] + pub fn get_items(&self) -> &[CString] { + return &self.items; + } } fn construct_envp(env: BTreeMap, saw_nul: &mut bool) -> CStringArray { diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 7f1f9353c6d09..f41bd2c20720a 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use env; +use ffi::CString; use io::{self, Error, ErrorKind}; use libc::{self, c_int, gid_t, pid_t, uid_t}; use ptr; @@ -39,13 +41,15 @@ impl Command { return Ok((ret, ours)) } + let possible_paths = self.compute_possible_paths(envp.as_ref()); + let (input, output) = sys::pipe::anon_pipe()?; let pid = unsafe { match cvt(libc::fork())? { 0 => { drop(input); - let err = self.do_exec(theirs, envp.as_ref()); + let err = self.do_exec(theirs, envp.as_ref(), possible_paths); let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; let bytes = [ (errno >> 24) as u8, @@ -113,12 +117,48 @@ impl Command { "nul byte found in provided data") } + let possible_paths = self.compute_possible_paths(envp.as_ref()); match self.setup_io(default, true) { - Ok((_, theirs)) => unsafe { self.do_exec(theirs, envp.as_ref()) }, + Ok((_, theirs)) => unsafe { self.do_exec(theirs, envp.as_ref(), possible_paths) }, Err(e) => e, } } + fn compute_possible_paths(&self, maybe_envp: Option<&CStringArray>) -> Option> { + let program = self.get_program().as_bytes(); + if program.contains(&b'/') { + return None; + } + // Outside the match so we can borrow it for the lifetime of the function. + let parent_path = env::var("PATH").ok(); + let paths = match maybe_envp { + Some(envp) => { + match envp.get_items().iter().find(|var| var.as_bytes().starts_with(b"PATH=")) { + Some(p) => &p.as_bytes()[5..], + None => return None, + } + }, + // maybe_envp is None if the process isn't changing the parent's env at all. + None => { + match parent_path.as_ref() { + Some(p) => p.as_bytes(), + None => return None, + } + }, + }; + + let mut possible_paths = vec![]; + for path in paths.split(|p| *p == b':') { + let mut binary_path = Vec::with_capacity(program.len() + path.len() + 1); + binary_path.extend_from_slice(path); + binary_path.push(b'/'); + binary_path.extend_from_slice(program); + let c_binary_path = CString::new(binary_path).unwrap(); + possible_paths.push(c_binary_path); + } + return Some(possible_paths); + } + // And at this point we've reached a special time in the life of the // child. The child must now be considered hamstrung and unable to // do anything other than syscalls really. Consider the following @@ -152,7 +192,8 @@ impl Command { unsafe fn do_exec( &mut self, stdio: ChildPipes, - maybe_envp: Option<&CStringArray> + maybe_envp: Option<&CStringArray>, + maybe_possible_paths: Option>, ) -> io::Error { use sys::{self, cvt_r}; @@ -193,9 +234,6 @@ impl Command { if let Some(ref cwd) = *self.get_cwd() { t!(cvt(libc::chdir(cwd.as_ptr()))); } - if let Some(envp) = maybe_envp { - *sys::os::environ() = envp.as_ptr(); - } // emscripten has no signal support. #[cfg(not(any(target_os = "emscripten")))] @@ -231,8 +269,53 @@ impl Command { t!(callback()); } - libc::execvp(self.get_argv()[0], self.get_argv().as_ptr()); - io::Error::last_os_error() + // If the program isn't an absolute path, and our environment contains a PATH var, then we + // implement the PATH traversal ourselves so that it honors the child's PATH instead of the + // parent's. This mirrors the logic that exists in glibc's execvpe, except using the + // child's env to fetch PATH. + match maybe_possible_paths { + Some(possible_paths) => { + let mut pending_error = None; + for path in possible_paths { + libc::execve( + path.as_ptr(), + self.get_argv().as_ptr(), + maybe_envp.map(|envp| envp.as_ptr()).unwrap_or_else(|| *sys::os::environ()) + ); + let err = io::Error::last_os_error(); + match err.kind() { + io::ErrorKind::PermissionDenied => { + // If we saw a PermissionDenied, and none of the other entries in + // $PATH are successful, then we'll return the first EACCESS we see. + if pending_error.is_none() { + pending_error = Some(err); + } + }, + // Errors which indicate we failed to find a file are ignored and we try + // the next entry in the path. + io::ErrorKind::NotFound | io::ErrorKind::TimedOut => { + continue + }, + // Any other error means we found a file and couldn't execute it. + _ => { + return err; + } + } + } + if let Some(err) = pending_error { + return err; + } + return io::Error::from_raw_os_error(libc::ENOENT); + }, + _ => { + libc::execve( + self.get_argv()[0], + self.get_argv().as_ptr(), + maybe_envp.map(|envp| envp.as_ptr()).unwrap_or_else(|| *sys::os::environ()) + ); + return io::Error::last_os_error() + } + } } #[cfg(not(any(target_os = "macos", target_os = "freebsd", diff --git a/src/test/run-pass/command-exec.rs b/src/test/run-pass/command-exec.rs index 46b409fb13a84..96f9da67790fc 100644 --- a/src/test/run-pass/command-exec.rs +++ b/src/test/run-pass/command-exec.rs @@ -48,6 +48,13 @@ fn main() { println!("passed"); } + "exec-test5" => { + env::set_var("VARIABLE", "ABC"); + Command::new("definitely-not-a-real-binary").env("VARIABLE", "XYZ").exec(); + assert_eq!(env::var("VARIABLE").unwrap(), "ABC"); + println!("passed"); + } + _ => panic!("unknown argument: {}", arg), } return @@ -72,4 +79,9 @@ fn main() { assert!(output.status.success()); assert!(output.stderr.is_empty()); assert_eq!(output.stdout, b"passed\n"); + + let output = Command::new(&me).arg("exec-test5").output().unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); } diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs index 6cf06d1562104..e6dd421f48f51 100644 --- a/src/test/run-pass/impl-trait/example-calendar.rs +++ b/src/test/run-pass/impl-trait/example-calendar.rs @@ -310,10 +310,10 @@ trait IteratorExt: Iterator + Sized { where Self::Item: std::fmt::Display { let mut s = String::new(); if let Some(e) = self.next() { - write!(s, "{}", e); + write!(s, "{}", e).unwrap(); for e in self { s.push_str(sep); - write!(s, "{}", e); + write!(s, "{}", e).unwrap(); } } s @@ -537,7 +537,7 @@ fn format_weeks(it: impl Iterator) -> impl Iterator2}", d.day()); + write!(buf, " {:>2}", d.day()).unwrap(); } // Insert more filler at the end to fill up the remainder of the week, diff --git a/src/test/run-pass/macros/colorful-write-macros.rs b/src/test/run-pass/macros/colorful-write-macros.rs index 7c557eb2bd079..ee597f11c6a9d 100644 --- a/src/test/run-pass/macros/colorful-write-macros.rs +++ b/src/test/run-pass/macros/colorful-write-macros.rs @@ -27,18 +27,18 @@ impl fmt::Write for Bar { } fn borrowing_writer_from_struct_and_formatting_struct_field(foo: Foo) { - write!(foo.writer, "{}", foo.other); + write!(foo.writer, "{}", foo.other).unwrap(); } fn main() { let mut w = Vec::new(); - write!(&mut w as &mut Write, ""); - write!(&mut w, ""); // should coerce + write!(&mut w as &mut Write, "").unwrap(); + write!(&mut w, "").unwrap(); // should coerce println!("ok"); let mut s = Bar; { use std::fmt::Write; - write!(&mut s, "test"); + write!(&mut s, "test").unwrap(); } } diff --git a/src/test/ui/macros/must-use-in-macro-55516.rs b/src/test/ui/macros/must-use-in-macro-55516.rs new file mode 100644 index 0000000000000..ad7cc37da52ca --- /dev/null +++ b/src/test/ui/macros/must-use-in-macro-55516.rs @@ -0,0 +1,21 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass +// compile-flags: -Wunused + +// make sure write!() can't hide its unused Result + +fn main() { + use std::fmt::Write; + let mut example = String::new(); + write!(&mut example, "{}", 42); //~WARN must be used +} + diff --git a/src/test/ui/macros/must-use-in-macro-55516.stderr b/src/test/ui/macros/must-use-in-macro-55516.stderr new file mode 100644 index 0000000000000..b03a5806da5c3 --- /dev/null +++ b/src/test/ui/macros/must-use-in-macro-55516.stderr @@ -0,0 +1,10 @@ +warning: unused `std::result::Result` that must be used + --> $DIR/must-use-in-macro-55516.rs:19:5 + | +LL | write!(&mut example, "{}", 42); //~WARN must be used + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-W unused-must-use` implied by `-W unused` + = note: this `Result` may be an `Err` variant, which should be handled + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) +