jiebi/CodeConvo huggingface dataset:
<ins> // compile-flags: -C no-prepopulate-passes #![crate_type="rlib"] #[allow(dead_code)] pub struct Foo<T> { foo: u64, bar: T, } // The store writing to bar.1 should have alignment 4. Not checking // other stores here, as the alignment will be platform-dependent. // CHECK: store i32 [[TMP1:%.+]], i32* [[TMP2:%.+]], align 4 #[no_mangle] pub fn test(x: (i32, i32)) -> Foo<(i32, i32)> { Foo { foo: 0, bar: x } } </ins>
println!("cargo:rustc-link-lib=advapi32"); println!("cargo:rustc-link-lib=ws2_32"); println!("cargo:rustc-link-lib=userenv"); <del> println!("cargo:rustc-link-lib=shell32"); </del> } else if target.contains("fuchsia") { println!("cargo:rustc-link-lib=zircon"); println!("cargo:rustc-link-lib=fdio");
#![allow(dead_code)] // runtime init functions not used during testing use os::windows::prelude::*; <ins> use sys::windows::os::current_exe; </ins> use sys::c; <del> use slice; use ops::Range; </del> use ffi::OsString; <del> use libc::{c_int, c_void}; </del> use fmt; <ins> use vec; use core::iter; use slice; use path::PathBuf; </ins> pub unsafe fn init(_argc: isize, _argv: *const *const u8) { }
impl<'a> fmt::Debug for ArgsInnerDebug<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { <del> f.write_str("[")?; let mut first = true; for i in self.args.range.clone() { if !first { f.write_str(", ")?; } first = false; // Here we do allocation which could be avoided. fmt::Debug::fmt(&unsafe { os_string_from_ptr(*self.args.cur.offset(i)) }, f)?; } f.write_str("]")?; Ok(()) </del> <ins> self.args.parsed_args_list.as_slice().fmt(f) </ins> } }
} } <del> unsafe fn os_string_from_ptr(ptr: *mut u16) -> OsString { let mut len = 0; while *ptr.offset(len) != 0 { len += 1; } // Push it onto the list. let ptr = ptr as *const u16; let buf = slice::from_raw_parts(ptr, len as usize); OsStringExt::from_wide(buf) } </del> impl Iterator for Args { type Item = OsString; <del> fn next(&mut self) -> Option<OsString> { self.range.next().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } ) } fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() } </del> <ins> fn next(&mut self) -> Option<OsString> { self.parsed_args_list.next() } fn size_hint(&self) -> (usize, Option<usize>) { self.parsed_args_list.size_hint() } </ins> } impl DoubleEndedIterator for Args { <del> fn next_back(&mut self) -> Option<OsString> { self.range.next_back().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } ) } </del> <ins> fn next_back(&mut self) -> Option<OsString> { self.parsed_args_list.next_back() } </ins> } impl ExactSizeIterator for Args { <del> fn len(&self) -> usize { self.range.len() } </del> <ins> fn len(&self) -> usize { self.parsed_args_list.len() } </ins> } <del> impl Drop for Args { fn drop(&mut self) { // self.cur can be null if CommandLineToArgvW previously failed, // but LocalFree ignores NULL pointers unsafe { c::LocalFree(self.cur as *mut c_void); } </del> <ins> #[cfg(test)] mod tests { use sys::windows::args::*; use ffi::OsString; fn chk(string: &str, parts: &[&str]) { let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect(); wide.push(0); let parsed = unsafe { parse_lp_cmd_line(wide.as_ptr() as *const u16, || OsString::from("TEST.EXE")) }; let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect(); assert_eq!(parsed.as_slice(), expected.as_slice()); } #[test] fn empty() { chk("", &["TEST.EXE"]); chk("0", &["TEST.EXE"]); } #[test] fn single_words() { chk("EXE one_word", &["EXE", "one_word"]); chk("EXE a", &["EXE", "a"]); chk("EXE 😅", &["EXE", "😅"]); chk("EXE 😅🤦", &["EXE", "😅🤦"]); } #[test] fn official_examples() { chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]); chk(r#"EXE ab d"e f"g h"#, &["EXE", r#"ab"#, "de fg", "h"]); chk(r#"EXE a"b c d"#, &["EXE", r#"a"b"#, "c", "d"]); chk(r#"EXE a"b c" d e"#, &["EXE", r#"ab c"#, "d", "e"]); } #[test] fn whitespace_behavior() { chk(r#" test"#, &["", "test"]); chk(r#"  test"#, &["", "test"]); chk(r#" test test2"#, &["", "test", "test2"]); chk(r#" test  test2"#, &["", "test", "test2"]); chk(r#"test test2 "#, &["test", "test2"]); chk(r#"test  test2 "#, &["test", "test2"]); chk(r#"test "#, &["test"]); } #[test] fn genius_quotes() { chk(r#"EXE "" """#, &["EXE", "", ""]); chk(r#"EXE "" """"#, &["EXE", "", """]); chk( r#"EXE "this is """all""" in the same argument""#, &["EXE", "this is "all" in the same argument"] ); chk(r#"EXE "a"""#, &["EXE", "a""]); chk(r#"EXE "a"" a"#, &["EXE", "a"", "a"]); // quotes cannot be escaped in command names chk(r#""EXE" check"#, &["EXE", "check"]); chk(r#""EXE check""#, &["EXE check"]); chk(r#""EXE """for""" check"#, &["EXE ", r#"for""#, "check"]); chk(r#""EXE "for" check"#, &[r#"EXE "#, r#"for""#,  "check"]); </ins> } }
pub fn SetLastError(dwErrCode: DWORD); pub fn GetCommandLineW() -> *mut LPCWSTR; <del> pub fn LocalFree(ptr: *mut c_void); pub fn CommandLineToArgvW(lpCmdLine: *mut LPCWSTR, pNumArgs: *mut c_int) -> *mut *mut u16; </del> pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD; pub fn OpenProcessToken(ProcessHandle: HANDLE,
# Extra flags needed to compile a working executable with the standard library ifdef IS_WINDOWS ifdef IS_MSVC <del> EXTRACFLAGS := ws2_32.lib userenv.lib shell32.lib advapi32.lib </del> <ins> EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib </ins> else EXTRACFLAGS := -lws2_32 -luserenv endif
/// ``` #[lang = "index"] #[rustc_on_unimplemented( <ins> on( _Self="&str", note="you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" ), on( _Self="str", note="you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" ), on( _Self="std::string::String", note="you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" ), </ins> message="the type `{Self}` cannot be indexed by `{Idx}`", label="`{Self}` cannot be indexed by `{Idx}`", )]
/// ``` #[lang = "index_mut"] #[rustc_on_unimplemented( <ins> on( _Self="&str", note="you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" ), on( _Self="str", note="you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" ), on( _Self="std::string::String", note="you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" ), </ins> message="the type `{Self}` cannot be mutably indexed by `{Idx}`", label="`{Self}` cannot be mutably indexed by `{Idx}`", )]
|                 ^^^^ `str` cannot be indexed by `{integer}` | = help: the trait `std::ops::Index<{integer}>` is not implemented for `str` <ins> = note: you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings> </ins> error: aborting due to previous error
|     ^^^^^^^^^ `str` cannot be mutably indexed by `usize` | = help: the trait `std::ops::IndexMut<usize>` is not implemented for `str` <ins> = note: you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings> </ins> error: aborting due to 3 previous errors
!preds.is_empty() && { let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_root_empty, ty); preds.iter().all(|t| { <del> let ty_params = &t.skip_binder().trait_ref.substs.iter().skip(1).collect::<Vec<_>>(); </del> <ins> let ty_params = &t .skip_binder() .trait_ref .substs .iter() .skip(1) .collect::<Vec<_>>(); </ins> implements_trait(cx, ty_empty_region, t.def_id(), ty_params) }) },
if let (Some(fmt_str), expr) = self.check_tts(cx, &mac.args.inner_tokens(), true) { if fmt_str.symbol == Symbol::intern("") { let mut applicability = Applicability::MachineApplicable; <del> let suggestion = if let Some(e) = expr { snippet_with_applicability(cx, e.span, "v", &mut applicability) } else { applicability = Applicability::HasPlaceholders; Cow::Borrowed("v") </del> <ins> let suggestion = match expr { Some(expr) => snippet_with_applicability(cx, expr.span, "v", &mut applicability), None => { applicability = Applicability::HasPlaceholders; Cow::Borrowed("v") }, </ins> }; span_lint_and_sugg(
/// /// The following return false: /// <del> /// - private address (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) /// - the loopback address (127.0.0.0/8) /// - the link-local address (169.254.0.0/16) /// - the broadcast address (255.255.255.255/32) /// - test addresses used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24) /// - the unspecified address (0.0.0.0) </del> <ins> /// - private addresses (see [`is_private()`](#method.is_private)) /// - the loopback address (see [`is_loopback()`](#method.is_loopback)) /// - the link-local address (see [`is_link_local()`](#method.is_link_local)) /// - the broadcast address (see [`is_broadcast()`](#method.is_broadcast)) /// - addresses used for documentation (see [`is_documentation()`](#method.is_documentation)) /// - the unspecified address (see [`is_unspecified()`](#method.is_unspecified)), and the whole ///   0.0.0.0/8 block /// - addresses reserved for future protocols (see /// [`is_ietf_protocol_assignment()`](#method.is_ietf_protocol_assignment), except /// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable /// - addresses reserved for future use (see [`is_reserved()`](#method.is_reserved) /// - addresses reserved for networking devices benchmarking (see /// [`is_benchmarking`](#method.is_benchmarking)) </ins> /// /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml /// [`true`]: ../../std/primitive.bool.html
/// use std::net::Ipv6Addr; /// /// fn main() { <del> ///     assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_link_local(), ///                false); ///     assert_eq!(Ipv6Addr::new(0xfe8a, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true); </del> <ins> ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0); ///     assert!(ip.is_unicast_link_local()); /// ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff); ///     assert!(ip.is_unicast_link_local()); /// ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0); ///     assert!(ip.is_unicast_link_local()); ///     assert!(!ip.is_unicast_link_local_strict()); /// ///     let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0); ///     assert!(ip.is_unicast_link_local()); ///     assert!(!ip.is_unicast_link_local_strict()); </ins> /// } /// ``` <ins> /// /// # See also /// /// - [IETF RFC 4291 section 2.4] /// - [RFC 4291 errata 4406] /// /// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4 /// [`true`]: ../../std/primitive.bool.html /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406 /// [`is_unicast_link_local_strict()`]: ../../std/net/struct.Ipv6Addr.html#method.is_unicast_link_local_strict /// </ins> pub fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 } <del> /// Returns [`true`] if this is a deprecated unicast site-local address /// (fec0::/10). </del> <ins> /// Returns [`true`] if this is a deprecated unicast site-local address (fec0::/10). The /// unicast site-local address format is defined in [RFC 4291 section 2.5.7] as: /// /// ```no_rust /// |   10     | /// |  bits    |         54 bits         |         64 bits            | /// +----------+-------------------------+----------------------------+ /// |1111111011|        subnet ID        |       interface ID         | /// +----------+-------------------------+----------------------------+ /// ``` </ins> /// /// [`true`]: ../../std/primitive.bool.html <ins> /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7 </ins> /// /// # Examples ///
/// /// - the loopback address /// - the link-local addresses <del> /// - the (deprecated) site-local addresses </del> /// - unique local addresses /// - the unspecified address /// - the address range reserved for documentation /// <ins> /// This method returns [`true`] for site-local addresses as per [RFC 4291 section 2.5.7] /// /// ```no_rust /// The special behavior of [the site-local unicast] prefix defined in [RFC3513] must no longer /// be supported in new implementations (i.e., new implementations must treat this prefix as /// Global Unicast). /// ``` /// </ins> /// [`true`]: ../../std/primitive.bool.html <ins> /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7 </ins> /// /// # Examples ///
/// ``` pub fn is_unicast_global(&self) -> bool { !self.is_multicast() <del> && !self.is_loopback() && !self.is_unicast_link_local() && !self.is_unicast_site_local() && !self.is_unique_local() && !self.is_unspecified() && !self.is_documentation() </del> <ins> && !self.is_loopback() && !self.is_unicast_link_local() && !self.is_unique_local() && !self.is_unspecified() && !self.is_documentation() </ins> } /// Returns the address's multicast scope if the address is multicast.
<ins> // Regression test for issue #57611 // Ensures that we don't ICE // FIXME: This should compile, but it currently doesn't #![feature(trait_alias)] #![feature(type_alias_impl_trait)] trait Foo { type Bar: Baz<Self, Self>; fn bar(&self) -> Self::Bar; } struct X; impl Foo for X { type Bar = impl Baz<Self, Self>; //~ ERROR type mismatch in closure arguments //~^ ERROR type mismatch resolving fn bar(&self) -> Self::Bar { |x| x } } trait Baz<A, B> = Fn(&A) -> &B; fn main() {} </ins>
<ins> error[E0631]: type mismatch in closure arguments --> $DIR/issue-57611-trait-alias.rs:17:5 | LL |     type Bar = impl Baz<Self, Self>; |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `for<'r> fn(&'r X) -> _` ... LL |         |x| x |         ----- found signature of `fn(_) -> _` | = note: the return type of a function must have a statically known size error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/issue-57611-trait-alias.rs:21:9: 21:14] as std::ops::FnOnce<(&'r X,)>>::Output == &'r X` --> $DIR/issue-57611-trait-alias.rs:17:5 | LL |     type Bar = impl Baz<Self, Self>; |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime | = note: the return type of a function must have a statically known size error: aborting due to 2 previous errors Some errors have detailed explanations: E0271, E0631. For more information about an error, try `rustc --explain E0271`. </ins>
<ins> // Regression test for issue #57807 - ensure // that we properly unify associated types within // a type alias impl trait // check-pass #![feature(type_alias_impl_trait)] trait Bar { type A; } impl Bar for () { type A = (); } trait Foo { type A; type B: Bar<A = Self::A>; fn foo() -> Self::B; } impl Foo for () { type A = (); type B = impl Bar<A = Self::A>; fn foo() -> Self::B { () } } fn main() {} </ins>
[[package]] name = "compiler_builtins" <del> version = "0.1.32" </del> <ins> version = "0.1.35" </ins> source = "registry+https://github.com/rust-lang/crates.io-index" <del> checksum = "7bc4ac2c824d2bfc612cba57708198547e9a26943af0632aff033e0693074d5c" </del> <ins> checksum = "e3fcd8aba10d17504c87ef12d4f62ef404c6a4703d16682a9eb5543e6cf24455" </ins> dependencies = [ "cc", "rustc-std-workspace-core",
panic_abort = { path = "../panic_abort" } core = { path = "../core" } libc = { version = "0.2.74", default-features = false, features = ['rustc-dep-of-std'] } <del> compiler_builtins = { version = "0.1.32" } </del> <ins> compiler_builtins = { version = "0.1.35" } </ins> profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } hashbrown = { version = "0.8.1", default-features = false, features = ['rustc-dep-of-std'] }
<ins> #![feature(never_type, specialization)] #![allow(incomplete_features)] use std::iter::{self, Empty}; trait Trait { type Out: Iterator<Item = u32>; fn f(&self) -> Option<Self::Out>; } impl<T> Trait for T { default type Out = !; //~ ERROR: `!` is not an iterator default fn f(&self) -> Option<Self::Out> { None } } struct X; impl Trait for X { type Out = Empty<u32>; fn f(&self) -> Option<Self::Out> { Some(iter::empty()) } } fn f<T: Trait>(a: T) { if let Some(iter) = a.f() { println!("Some"); for x in iter { println!("x = {}", x); } } } pub fn main() { f(10); } </ins>
<ins> error[E0277]: `!` is not an iterator --> $DIR/issue-51506.rs:13:5 | LL |     type Out: Iterator<Item = u32>; |     ------------------------------- required by `Trait::Out` ... LL |     default type Out = !; |     ^^^^^^^^^^^^^^^^^^^^^ `!` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `!` error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>
<ins> #![crate_type = "lib"] #![feature(specialization)] #![feature(unsize, coerce_unsized)] #![allow(incomplete_features)] use std::ops::CoerceUnsized; pub struct SmartassPtr<A: Smartass+?Sized>(A::Data); pub trait Smartass { type Data; type Data2: CoerceUnsized<*const [u8]>; } pub trait MaybeObjectSafe {} impl MaybeObjectSafe for () {} impl<T> Smartass for T { type Data = <Self as Smartass>::Data2; default type Data2 = (); //~^ ERROR: the trait bound `(): std::ops::CoerceUnsized<*const [u8]>` is not satisfied } impl Smartass for () { type Data2 = *const [u8; 1]; } impl Smartass for dyn MaybeObjectSafe { type Data = *const [u8]; type Data2 = *const [u8; 0]; } impl<U: Smartass+?Sized, T: Smartass+?Sized> CoerceUnsized<SmartassPtr<T>> for SmartassPtr<U> where <U as Smartass>::Data: std::ops::CoerceUnsized<<T as Smartass>::Data> {} pub fn conv(s: SmartassPtr<()>) -> SmartassPtr<dyn MaybeObjectSafe> { s } </ins>
<ins> error[E0277]: the trait bound `(): std::ops::CoerceUnsized<*const [u8]>` is not satisfied --> $DIR/issue-44861.rs:21:5 | LL |     type Data2: CoerceUnsized<*const [u8]>; |     --------------------------------------- required by `Smartass::Data2` ... LL |     default type Data2 = (); |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::CoerceUnsized<*const [u8]>` is not implemented for `()` error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>
<ins> #![feature(specialization)] #![allow(incomplete_features)] struct MyStruct {} trait MyTrait { type MyType: Default; } impl MyTrait for i32 { default type MyType = MyStruct; //~^ ERROR: the trait bound `MyStruct: std::default::Default` is not satisfied } fn main() { let _x: <i32 as MyTrait>::MyType = <i32 as MyTrait>::MyType::default(); } </ins>
<ins> error[E0277]: the trait bound `MyStruct: std::default::Default` is not satisfied --> $DIR/issue-59435.rs:11:5 | LL |     type MyType: Default; |     --------------------- required by `MyTrait::MyType` ... LL |     default type MyType = MyStruct; |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::default::Default` is not implemented for `MyStruct` error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>
<ins> // only-x86_64 #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; unsafe fn pclmul(a: __m128i, b: __m128i) -> __m128i { let imm8 = 3; _mm_clmulepi64_si128(a, b, imm8) //~ ERROR argument 3 is required to be a constant } fn main() {} </ins>
<ins> // only-x86_64 #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; unsafe fn pclmul(a: __m128i, b: __m128i) -> __m128i { _mm_clmulepi64_si128(a, b, *&mut 42) //~ ERROR argument 3 is required to be a constant } fn main() {} </ins>
<ins> // only-x86_64 #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; unsafe fn pclmul(a: __m128i, b: __m128i, imm8: i32) -> __m128i { _mm_clmulepi64_si128(a, b, imm8) //~ ERROR argument 3 is required to be a constant } fn main() {} </ins>
<del> use errors::DiagnosticBuilder; </del> <ins> use errors::{Applicability, DiagnosticBuilder}; </ins> use syntax::ast::{self, *}; use syntax::source_map::Spanned; use syntax::ext::base::*; use syntax::ext::build::AstBuilder; use syntax::parse::token; <ins> use syntax::parse::parser::Parser; </ins> use syntax::print::pprust; use syntax::ptr::P; use syntax::symbol::Symbol;
return Err(err); } <del> Ok(Assert { cond_expr: parser.parse_expr()?, custom_message: if parser.eat(&token::Comma) { let ts = parser.parse_tokens(); if !ts.is_empty() { Some(ts) } else { None } } else { None }, }) </del> <ins> let cond_expr = parser.parse_expr()?; // Some crates use the `assert!` macro in the following form (note extra semicolon): // // assert!( //     my_function(); // ); // // Warn about semicolon and suggest removing it. Eventually, this should be turned into an // error. if parser.token == token::Semi { let mut err = cx.struct_span_warn(sp, "macro requires an expression as an argument"); err.span_suggestion( parser.span, "try removing semicolon", String::new(), Applicability::MaybeIncorrect ); err.note("this is going to be an error in the future"); err.emit(); parser.bump(); } // Some crates use the `assert!` macro in the following form (note missing comma before // message): // // assert!(true "error message"); // // Parse this as an actual message, and suggest inserting a comma. Eventually, this should be // turned into an error. let custom_message = if let token::Literal(token::Lit::Str_(_), _) = parser.token { let mut err = cx.struct_span_warn(parser.span, "unexpected string literal"); let comma_span = cx.source_map().next_point(parser.prev_span); err.span_suggestion_short( comma_span, "try adding a comma", ", ".to_string(), Applicability::MaybeIncorrect ); err.note("this is going to be an error in the future"); err.emit(); parse_custom_message(&mut parser) } else if parser.eat(&token::Comma) { parse_custom_message(&mut parser) } else { None }; if parser.token != token::Eof { parser.expect_one_of(&[], &[])?; unreachable!(); } Ok(Assert { cond_expr, custom_message }) } fn parse_custom_message<'a>(parser: &mut Parser<'a>) -> Option<TokenStream> { let ts = parser.parse_tokens(); if !ts.is_empty() { Some(ts) } else { None } </ins> }
<ins> // Ensure assert macro does not ignore trailing garbage. // // See https://github.com/rust-lang/rust/issues/60024 for details. fn main() { assert!(true some extra junk, "whatever"); //~^ ERROR expected one of assert!(true some extra junk); //~^ ERROR expected one of assert!(true, "whatever" blah); //~^ ERROR no rules expected assert!(true "whatever" blah); //~^ WARN unexpected string literal //~^^ ERROR no rules expected assert!(true;); //~^ WARN macro requires an expression assert!(false || true "error message"); //~^ WARN unexpected string literal } </ins>