diff --git a/.mailmap b/.mailmap index 2d5759b539e5d..679aa55d31458 100644 --- a/.mailmap +++ b/.mailmap @@ -5,8 +5,8 @@ # email addresses. # -Aaron Todd Aaron Power Erin Power +Aaron Todd Abhishek Chanda Abhishek Chanda Adolfo Ochagavía Adrien Tétar @@ -29,8 +29,8 @@ Ariel Ben-Yehuda Ariel Ben-Yehuda Ariel Ben-Yehuda arielb1 Austin Seipp Aydin Kim aydin.kim -Bastian Kauschke Barosl Lee Barosl LEE +Bastian Kauschke Ben Alpert Ben Sago Ben S Ben Sago Ben S @@ -46,22 +46,23 @@ Brian Anderson Brian Dawn Brian Leibig Brian Leibig Carl-Anton Ingmarsson +Carol (Nichols || Goulding) <193874+carols10cents@users.noreply.github.com> +Carol (Nichols || Goulding) Carol (Nichols || Goulding) -Carol (Nichols || Goulding) Carol Nichols Carol Willing Chris C Cerami Chris C Cerami Chris Pressey Chris Thorn Chris Thorn Chris Vittal Christopher Vittal -Christian Poveda Christian Poveda +Christian Poveda Clark Gaebel Clinton Ryan Corey Richardson Elaine "See More" Nemo Cyryl Płotnicki Damien Schoof -Daniel Ramos Daniel J Rollins +Daniel Ramos David Klein David Manescu David Ross @@ -70,9 +71,9 @@ Diggory Hardy Diggory Hardy Dylan Braithwaite Dzmitry Malyshau E. Dunham edunham +Eduard-Mihai Burtescu Eduardo Bautista <=> Eduardo Bautista -Eduard-Mihai Burtescu Elliott Slaughter Elly Fong-Jones Eric Holk @@ -80,8 +81,8 @@ Eric Holk Eric Holmes Eric Reed Erick Tryzelaar -Esteban Küber Esteban Küber +Esteban Küber Esteban Küber Evgeny Sologubov Falco Hirschenberger @@ -102,9 +103,9 @@ Herman J. Radtke III Herman J. Radtke III Ivan Ivaschenko J. J. Weber +Jakub Adam Wieczorek Jakub Adam Wieczorek Jakub Adam Wieczorek -Jakub Adam Wieczorek James Deng James Miller James Perry @@ -119,6 +120,7 @@ Jethro Beekman Jihyun Yu Jihyun Yu jihyun Jihyun Yu Jihyun Yu +João Oliveira joaoxsouls Johann Hofmann Johann John Clements John Hodge John Hodge @@ -129,7 +131,8 @@ Jonathan S Jonathan S Jonathan Turner Jorge Aparicio Joseph Martin -João Oliveira joaoxsouls +Joseph T. Lyons +Joseph T. Lyons Junyoung Cho Jyun-Yan You Kang Seonghoon @@ -145,8 +148,6 @@ Lindsey Kuper Luke Metz Luqman Aden Luqman Aden -NAKASHIMA, Makoto -NAKASHIMA, Makoto Marcell Pardavi Margaret Meyerhofer Mark Rousskov @@ -167,12 +168,14 @@ Michael Woerister Mickaël Raybaud-Roig m-r-r Ms2ger Mukilan Thiagarajan +NAKASHIMA, Makoto +NAKASHIMA, Makoto Nathan West Nathan Wilson Nathaniel Herman Nathaniel Herman Neil Pankey -Nicole Mazzuca Nick Platt +Nicole Mazzuca Nif Ward Oliver Schneider oli-obk Oliver Schneider Oliver 'ker' Schneider @@ -230,8 +233,8 @@ Tim JIANG Tim Joseph Dumol Torsten Weber Ty Overby -Ulrik Sverdrup bluss Ulrik Sverdrup bluss +Ulrik Sverdrup bluss Ulrik Sverdrup Ulrik Sverdrup Vadim Petrochenkov Vadim Petrochenkov petrochenkov diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index 2906e5824ae70..68606a4c1fbdc 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -5,6 +5,8 @@ //! Utilities related to FFI bindings. use crate::fmt; +use crate::marker::PhantomData; +use crate::ops::{Deref, DerefMut}; /// Equivalent to C's `void` type when used as a [pointer]. /// @@ -45,25 +47,33 @@ impl fmt::Debug for c_void { } /// Basic implementation of a `va_list`. +// The name is WIP, using `VaListImpl` for now. #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")), all(target_arch = "aarch64", target_os = "ios"), windows))] +#[repr(transparent)] #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -extern { - type VaListImpl; +#[lang = "va_list"] +pub struct VaListImpl<'f> { + ptr: *mut c_void, + _marker: PhantomData<&'f c_void>, } #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "x86_64")), all(target_arch = "aarch64", target_os = "ios"), windows))] -impl fmt::Debug for VaListImpl { +#[unstable(feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930")] +impl<'f> fmt::Debug for VaListImpl<'f> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "va_list* {:p}", self) + write!(f, "va_list* {:p}", self.ptr) } } @@ -79,12 +89,14 @@ impl fmt::Debug for VaListImpl { reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -struct VaListImpl { +#[lang = "va_list"] +pub struct VaListImpl<'f> { stack: *mut c_void, gr_top: *mut c_void, vr_top: *mut c_void, gr_offs: i32, vr_offs: i32, + _marker: PhantomData<&'f c_void>, } /// PowerPC ABI implementation of a `va_list`. @@ -95,12 +107,14 @@ struct VaListImpl { reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -struct VaListImpl { +#[lang = "va_list"] +pub struct VaListImpl<'f> { gpr: u8, fpr: u8, reserved: u16, overflow_arg_area: *mut c_void, reg_save_area: *mut c_void, + _marker: PhantomData<&'f c_void>, } /// x86_64 ABI implementation of a `va_list`. @@ -111,22 +125,99 @@ struct VaListImpl { reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -struct VaListImpl { +#[lang = "va_list"] +pub struct VaListImpl<'f> { gp_offset: i32, fp_offset: i32, overflow_arg_area: *mut c_void, reg_save_area: *mut c_void, + _marker: PhantomData<&'f c_void>, } /// A wrapper for a `va_list` -#[lang = "va_list"] +#[repr(transparent)] #[derive(Debug)] #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -#[repr(transparent)] -pub struct VaList<'a>(&'a mut VaListImpl); +pub struct VaList<'a, 'f: 'a> { + #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), + not(target_arch = "x86_64")), + all(target_arch = "aarch64", target_os = "ios"), + windows))] + inner: VaListImpl<'f>, + + #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", + target_arch = "x86_64"), + any(not(target_arch = "aarch64"), not(target_os = "ios")), + not(windows)))] + inner: &'a mut VaListImpl<'f>, + + _marker: PhantomData<&'a mut VaListImpl<'f>>, +} + +#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), + not(target_arch = "x86_64")), + all(target_arch = "aarch64", target_os = "ios"), + windows))] +#[unstable(feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930")] +impl<'f> VaListImpl<'f> { + /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`. + #[inline] + pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> { + VaList { + inner: VaListImpl { ..*self }, + _marker: PhantomData, + } + } +} + +#[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", + target_arch = "x86_64"), + any(not(target_arch = "aarch64"), not(target_os = "ios")), + not(windows)))] +#[unstable(feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930")] +impl<'f> VaListImpl<'f> { + /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`. + #[inline] + pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> { + VaList { + inner: self, + _marker: PhantomData, + } + } +} + +#[unstable(feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930")] +impl<'a, 'f: 'a> Deref for VaList<'a, 'f> { + type Target = VaListImpl<'f>; + + #[inline] + fn deref(&self) -> &VaListImpl<'f> { + &self.inner + } +} + +#[unstable(feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930")] +impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> { + #[inline] + fn deref_mut(&mut self) -> &mut VaListImpl<'f> { + &mut self.inner + } +} // The VaArgSafe trait needs to be used in public interfaces, however, the trait // itself must not be allowed to be used outside this module. Allowing users to @@ -175,56 +266,76 @@ impl sealed_trait::VaArgSafe for *mut T {} issue = "44930")] impl sealed_trait::VaArgSafe for *const T {} -impl<'a> VaList<'a> { +#[unstable(feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930")] +#[cfg(not(stage0))] +impl<'f> VaListImpl<'f> { /// Advance to the next arg. - #[unstable(feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930")] + #[inline] pub unsafe fn arg(&mut self) -> T { va_arg(self) } /// Copies the `va_list` at the current location. - #[unstable(feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930")] pub unsafe fn with_copy(&self, f: F) -> R - where F: for<'copy> FnOnce(VaList<'copy>) -> R { - #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), - not(target_arch = "x86_64")), - all(target_arch = "aarch64", target_os = "ios"), - windows))] - let mut ap = va_copy(self); - #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"), - not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))] - let mut ap_inner = va_copy(self); - #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"), - not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))] - let mut ap = VaList(&mut ap_inner); - let ret = f(VaList(ap.0)); + where F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R { + let mut ap = self.clone(); + let ret = f(ap.as_va_list()); va_end(&mut ap); ret } } +#[unstable(feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930")] +#[cfg(not(stage0))] +impl<'f> Clone for VaListImpl<'f> { + #[inline] + fn clone(&self) -> Self { + let mut dest = crate::mem::MaybeUninit::uninit(); + unsafe { + va_copy(dest.as_mut_ptr(), self); + dest.assume_init() + } + } +} + +#[unstable(feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930")] +#[cfg(not(stage0))] +impl<'f> Drop for VaListImpl<'f> { + fn drop(&mut self) { + // FIXME: this should call `va_end`, but there's no clean way to + // guarantee that `drop` always gets inlined into its caller, + // so the `va_end` would get directly called from the same function as + // the corresponding `va_copy`. `man va_end` states that C requires this, + // and LLVM basically follows the C semantics, so we need to make sure + // that `va_end` is always called from the same function as `va_copy`. + // For more details, see https://github.com/rust-lang/rust/pull/59625 + // and https://llvm.org/docs/LangRef.html#llvm-va-end-intrinsic. + // + // This works for now, since `va_end` is a no-op on all current LLVM targets. + } +} + extern "rust-intrinsic" { /// Destroy the arglist `ap` after initialization with `va_start` or /// `va_copy`. - fn va_end(ap: &mut VaList<'_>); + #[cfg(not(stage0))] + fn va_end(ap: &mut VaListImpl<'_>); /// Copies the current location of arglist `src` to the arglist `dst`. - #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"), - not(target_arch = "x86_64")), - all(target_arch = "aarch64", target_os = "ios"), - windows))] - fn va_copy<'a>(src: &VaList<'a>) -> VaList<'a>; - #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"), - not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))] - fn va_copy(src: &VaList<'_>) -> VaListImpl; + #[cfg(not(stage0))] + fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>); /// Loads an argument of type `T` from the `va_list` `ap` and increment the /// argument `ap` points to. - fn va_arg(ap: &mut VaList<'_>) -> T; + #[cfg(not(stage0))] + fn va_arg(ap: &mut VaListImpl<'_>) -> T; } diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index ce4aee7ebc54f..40f4354213b40 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -966,6 +966,9 @@ impl DerefMut for ManuallyDrop { /// /// The compiler then knows to not make any incorrect assumptions or optimizations on this code. /// +/// You can think of `MaybeUninit` as being a bit like `Option` but without +/// any of the run-time tracking and without any of the safety checks. +/// /// ## out-pointers /// /// You can use `MaybeUninit` to implement "out-pointers": instead of returning data diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index c5bcddcb26623..c50fe36cd70c6 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1523,7 +1523,7 @@ impl<'a> LoweringContext<'a> { } TyKind::Mac(_) => panic!("TyMac should have been expanded by now."), TyKind::CVarArgs => { - // Create the implicit lifetime of the "spoofed" `VaList`. + // Create the implicit lifetime of the "spoofed" `VaListImpl`. let span = self.sess.source_map().next_point(t.span.shrink_to_lo()); let lt = self.new_implicit_lifetime(span); hir::TyKind::CVarArgs(lt) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 1a6f5d3733e7a..c8f239a5ffa0c 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1882,7 +1882,7 @@ pub enum TyKind { Infer, /// Placeholder for a type that has failed to be defined. Err, - /// Placeholder for C-variadic arguments. We "spoof" the `VaList` created + /// Placeholder for C-variadic arguments. We "spoof" the `VaListImpl` created /// from the variadic arguments. This type is only valid up to typeck. CVarArgs(Lifetime), } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 6d7b0926c7ae2..622320e53bf78 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -2501,7 +2501,7 @@ where } // If this is a C-variadic function, this is not the return value, - // and there is one or more fixed arguments; ensure that the `VaList` + // and there is one or more fixed arguments; ensure that the `VaListImpl` // is ignored as an argument. if sig.c_variadic { match (last_arg_idx, arg_idx) { @@ -2512,7 +2512,7 @@ where }; match ty.sty { ty::Adt(def, _) if def.did == va_list_did => { - // This is the "spoofed" `VaList`. Set the arguments mode + // This is the "spoofed" `VaListImpl`. Set the arguments mode // so that it will be ignored. arg.mode = PassMode::Ignore(IgnoreMode::CVarArgs); } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 9ae0e26196d94..597c860cb57b8 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -143,15 +143,8 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.va_end(args[0].immediate()) } "va_copy" => { - let va_list = match (tcx.lang_items().va_list(), &result.layout.ty.sty) { - (Some(did), ty::Adt(def, _)) if def.did == did => args[0].immediate(), - (Some(_), _) => self.load(args[0].immediate(), - tcx.data_layout.pointer_align.abi), - (None, _) => bug!("`va_list` language item must be defined") - }; let intrinsic = self.cx().get_intrinsic(&("llvm.va_copy")); - self.call(intrinsic, &[llresult, va_list], None); - return; + self.call(intrinsic, &[args[0].immediate(), args[1].immediate()], None) } "va_arg" => { match fn_ty.ret.layout.abi { @@ -718,37 +711,12 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.call(expect, &[cond, self.const_bool(expected)], None) } - fn va_start(&mut self, list: &'ll Value) -> &'ll Value { - let target = &self.cx.tcx.sess.target.target; - let arch = &target.arch; - // A pointer to the architecture specific structure is passed to this - // function. For pointer variants (i686, RISC-V, Windows, etc), we - // should do do nothing, as the address to the pointer is needed. For - // architectures with a architecture specific structure (`Aarch64`, - // `X86_64`, etc), this function should load the structure from the - // address provided. - let va_list = match &**arch { - _ if target.options.is_like_windows => list, - "aarch64" if target.target_os == "ios" => list, - "aarch64" | "x86_64" | "powerpc" => - self.load(list, self.tcx().data_layout.pointer_align.abi), - _ => list, - }; + fn va_start(&mut self, va_list: &'ll Value) -> &'ll Value { let intrinsic = self.cx().get_intrinsic("llvm.va_start"); self.call(intrinsic, &[va_list], None) } - fn va_end(&mut self, list: &'ll Value) -> &'ll Value { - let target = &self.cx.tcx.sess.target.target; - let arch = &target.arch; - // See the comment in `va_start` for the purpose of the following. - let va_list = match &**arch { - _ if target.options.is_like_windows => list, - "aarch64" if target.target_os == "ios" => list, - "aarch64" | "x86_64" | "powerpc" => - self.load(list, self.tcx().data_layout.pointer_align.abi), - _ => list, - }; + fn va_end(&mut self, va_list: &'ll Value) -> &'ll Value { let intrinsic = self.cx().get_intrinsic("llvm.va_end"); self.call(intrinsic, &[va_list], None) } diff --git a/src/librustc_codegen_llvm/va_arg.rs b/src/librustc_codegen_llvm/va_arg.rs index 410e00fe0b885..86b0ad761af6a 100644 --- a/src/librustc_codegen_llvm/va_arg.rs +++ b/src/librustc_codegen_llvm/va_arg.rs @@ -132,16 +132,6 @@ pub(super) fn emit_va_arg( // For all other architecture/OS combinations fall back to using // the LLVM va_arg instruction. // https://llvm.org/docs/LangRef.html#va-arg-instruction - _ => { - let va_list = if (target.arch == "aarch64" || - target.arch == "x86_64" || - target.arch == "powerpc") && - !target.options.is_like_windows { - bx.load(addr.immediate(), bx.tcx().data_layout.pointer_align.abi) - } else { - addr.immediate() - }; - bx.va_arg(va_list, bx.cx.layout_of(target_ty).llvm_type(bx.cx)) - } + _ => bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) } } diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index c7dd019fc3eb8..8a11c01e896f2 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -507,7 +507,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } - // The "spoofed" `VaList` added to a C-variadic functions signature + // The "spoofed" `VaListImpl` added to a C-variadic functions signature // should not be included in the `extra_args` calculation. let extra_args_start_idx = sig.inputs().len() - if sig.c_variadic { 1 } else { 0 }; let extra_args = &args[extra_args_start_idx..]; @@ -691,7 +691,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (&args[..], None) }; - // Useful determining if the current argument is the "spoofed" `VaList` + // Useful determining if the current argument is the "spoofed" `VaListImpl` let last_arg_idx = if sig.inputs().is_empty() { None } else { @@ -699,7 +699,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; 'make_args: for (i, arg) in first_args.iter().enumerate() { // If this is a C-variadic function the function signature contains - // an "spoofed" `VaList`. This argument is ignored, but we need to + // an "spoofed" `VaListImpl`. This argument is ignored, but we need to // populate it with a dummy operand so that the users real arguments // are not overwritten. let i = if sig.c_variadic && last_arg_idx.map(|x| i >= x).unwrap_or(false) { diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index fed12c9a29fd2..2d0879e7b9f38 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -84,7 +84,7 @@ pub struct FunctionCx<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> { scopes: IndexVec>, /// If this function is a C-variadic function, this contains the `PlaceRef` of the - /// "spoofed" `VaList`. + /// "spoofed" `VaListImpl`. va_list_ref: Option>, } @@ -569,35 +569,24 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( indirect_operand.store(bx, tmp); tmp } else { + let tmp = PlaceRef::alloca(bx, arg.layout, &name); if fx.fn_ty.c_variadic && last_arg_idx.map(|idx| arg_index == idx).unwrap_or(false) { - let va_list_impl = match arg_decl.ty.ty_adt_def() { - Some(adt) => adt.non_enum_variant(), - None => bug!("`va_list` language item improperly constructed") + let va_list_did = match tcx.lang_items().va_list() { + Some(did) => did, + None => bug!("`va_list` lang item required for C-variadic functions"), }; - match tcx.type_of(va_list_impl.fields[0].did).sty { - ty::Ref(_, ty, _) => { - // If the underlying structure the `VaList` contains is a structure, - // we need to allocate it (e.g., X86_64 on Linux). - let tmp = PlaceRef::alloca(bx, arg.layout, &name); - if let ty::Adt(..) = ty.sty { - let layout = bx.layout_of(ty); - // Create an unnamed allocation for the backing structure - // and store it in the the spoofed `VaList`. - let backing = PlaceRef::alloca(bx, layout, ""); - bx.store(backing.llval, tmp.llval, layout.align.abi); - } - // Call `va_start` on the spoofed `VaList`. + match arg_decl.ty.sty { + ty::Adt(def, _) if def.did == va_list_did => { + // Call `va_start` on the spoofed `VaListImpl`. bx.va_start(tmp.llval); *va_list_ref = Some(tmp); - tmp - } - _ => bug!("improperly constructed `va_list` lang item"), + }, + _ => bug!("last argument of variadic function is not a `va_list`") } } else { - let tmp = PlaceRef::alloca(bx, arg.layout, &name); bx.store_fn_arg(arg, &mut llarg_idx, tmp); - tmp } + tmp }; let upvar_debuginfo = &mir.__upvar_debuginfo_codegen_only_do_not_use; arg_scope.map(|scope| { diff --git a/src/librustc_codegen_ssa/traits/intrinsic.rs b/src/librustc_codegen_ssa/traits/intrinsic.rs index cd5278989778f..ede30a0bed756 100644 --- a/src/librustc_codegen_ssa/traits/intrinsic.rs +++ b/src/librustc_codegen_ssa/traits/intrinsic.rs @@ -20,10 +20,10 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes { fn abort(&mut self); fn assume(&mut self, val: Self::Value); fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value; - /// Trait method used to inject `va_start` on the "spoofed" `VaList` in + /// Trait method used to inject `va_start` on the "spoofed" `VaListImpl` in /// Rust defined C-variadic functions. fn va_start(&mut self, val: Self::Value) -> Self::Value; - /// Trait method used to inject `va_end` on the "spoofed" `VaList` before + /// Trait method used to inject `va_end` on the "spoofed" `VaListImpl` before /// Rust defined C-variadic functions return. fn va_end(&mut self, val: Self::Value) -> Self::Value; } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index ac18e131c4a3d..6a6f6e48ef538 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -883,7 +883,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let sig = self.cx.tcx.fn_sig(def_id); let sig = self.cx.tcx.erase_late_bound_regions(&sig); let inputs = if sig.c_variadic { - // Don't include the spoofed `VaList` in the functions list + // Don't include the spoofed `VaListImpl` in the functions list // of inputs. &sig.inputs()[..sig.inputs().len() - 1] } else { diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index de8e75ca277ee..2ef322743c5f3 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1695,7 +1695,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { from_hir_call: bool, ) { debug!("check_call_inputs({:?}, {:?})", sig, args); - // Do not count the `VaList` argument as a "true" argument to + // Do not count the `VaListImpl` argument as a "true" argument to // a C-variadic function. let inputs = if sig.c_variadic { &sig.inputs()[..sig.inputs().len() - 1] diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index c6191e6b579ce..86ce8f6df073a 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -83,12 +83,15 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let param = |n| tcx.mk_ty_param(n, InternedString::intern(&format!("P{}", n))); let name = it.ident.as_str(); - let mk_va_list_ty = || { + let mk_va_list_ty = |mutbl| { tcx.lang_items().va_list().map(|did| { let region = tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0))); let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]); - tcx.mk_mut_ref(tcx.mk_region(env_region), va_list_ty) + (tcx.mk_ref(tcx.mk_region(env_region), ty::TypeAndMut { + ty: va_list_ty, + mutbl + }), va_list_ty) }) }; @@ -335,42 +338,25 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } "va_start" | "va_end" => { - match mk_va_list_ty() { - Some(va_list_ty) => (0, vec![va_list_ty], tcx.mk_unit()), + match mk_va_list_ty(hir::MutMutable) { + Some((va_list_ref_ty, _)) => (0, vec![va_list_ref_ty], tcx.mk_unit()), None => bug!("`va_list` language item needed for C-variadic intrinsics") } } "va_copy" => { - match tcx.lang_items().va_list() { - Some(did) => { - let region = tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0))); - let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); - let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]); - let ret_ty = match va_list_ty.sty { - ty::Adt(def, _) if def.is_struct() => { - let fields = &def.non_enum_variant().fields; - match tcx.type_of(fields[0].did).subst(tcx, &[region.into()]).sty { - ty::Ref(_, element_ty, _) => match element_ty.sty { - ty::Adt(..) => element_ty, - _ => va_list_ty - } - _ => bug!("va_list structure is invalid") - } - } - _ => { - bug!("va_list structure is invalid") - } - }; - (0, vec![tcx.mk_imm_ref(tcx.mk_region(env_region), va_list_ty)], ret_ty) + match mk_va_list_ty(hir::MutImmutable) { + Some((va_list_ref_ty, va_list_ty)) => { + let va_list_ptr_ty = tcx.mk_mut_ptr(va_list_ty); + (0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.mk_unit()) } None => bug!("`va_list` language item needed for C-variadic intrinsics") } } "va_arg" => { - match mk_va_list_ty() { - Some(va_list_ty) => (1, vec![va_list_ty], param(0)), + match mk_va_list_ty(hir::MutMutable) { + Some((va_list_ref_ty, _)) => (1, vec![va_list_ref_ty], param(0)), None => bug!("`va_list` language item needed for C-variadic intrinsics") } } diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 7a38f0ebd5a57..69fcfa8b39ca5 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -170,7 +170,7 @@ pub use core::ffi::c_void; reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -pub use core::ffi::VaList; +pub use core::ffi::{VaList, VaListImpl}; mod c_str; mod os_str; diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index e309f81192cf3..d0e56acc8fb27 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -1162,6 +1162,41 @@ mod tests { assert_eq!(reader.get_ref().pos, expected); } + #[test] + fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() { + // gimmick reader that returns Err after first seek + struct ErrAfterFirstSeekReader { + first_seek: bool, + } + impl Read for ErrAfterFirstSeekReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + for x in &mut *buf { + *x = 0; + } + Ok(buf.len()) + } + } + impl Seek for ErrAfterFirstSeekReader { + fn seek(&mut self, _: SeekFrom) -> io::Result { + if self.first_seek { + self.first_seek = false; + Ok(0) + } else { + Err(io::Error::new(io::ErrorKind::Other, "oh no!")) + } + } + } + + let mut reader = BufReader::with_capacity(5, ErrAfterFirstSeekReader { first_seek: true }); + assert_eq!(reader.fill_buf().ok(), Some(&[0, 0, 0, 0, 0][..])); + + // The following seek will require two underlying seeks. The first will + // succeed but the second will fail. This should still invalidate the + // buffer. + assert!(reader.seek(SeekFrom::Current(i64::min_value())).is_err()); + assert_eq!(reader.buffer().len(), 0); + } + #[test] fn test_buffered_writer() { let inner = Vec::new(); diff --git a/src/test/auxiliary/rust_test_helpers.c b/src/test/auxiliary/rust_test_helpers.c index 27a26d244c23a..7f2afd9c5715c 100644 --- a/src/test/auxiliary/rust_test_helpers.c +++ b/src/test/auxiliary/rust_test_helpers.c @@ -216,20 +216,27 @@ uint64_t get_c_many_params(void *a, void *b, void *c, void *d, struct quad f) { } // Calculates the average of `(x + y) / n` where x: i64, y: f64. There must be exactly n pairs -// passed as variadic arguments. -double rust_interesting_average(uint64_t n, ...) { - va_list pairs; +// passed as variadic arguments. There are two versions of this function: the +// variadic one, and the one that takes a `va_list`. +double rust_valist_interesting_average(uint64_t n, va_list pairs) { double sum = 0.0; int i; - va_start(pairs, n); for(i = 0; i < n; i += 1) { sum += (double)va_arg(pairs, int64_t); sum += va_arg(pairs, double); } - va_end(pairs); return sum / n; } +double rust_interesting_average(uint64_t n, ...) { + double sum; + va_list pairs; + va_start(pairs, n); + sum = rust_valist_interesting_average(n, pairs); + va_end(pairs); + return sum; +} + int32_t rust_int8_to_int32(int8_t x) { return (int32_t)x; } diff --git a/src/test/codegen/c-variadic-copy.rs b/src/test/codegen/c-variadic-copy.rs new file mode 100644 index 0000000000000..4c61c4fcf68d3 --- /dev/null +++ b/src/test/codegen/c-variadic-copy.rs @@ -0,0 +1,16 @@ +// Tests that `VaListImpl::clone` gets inlined into a call to `llvm.va_copy` + +#![crate_type = "lib"] +#![feature(c_variadic)] +#![no_std] +use core::ffi::VaList; + +extern "C" { + fn foreign_c_variadic_1(_: VaList, ...); +} + +pub unsafe extern "C" fn clone_variadic(ap: VaList) { + let mut ap2 = ap.clone(); + // CHECK: call void @llvm.va_copy + foreign_c_variadic_1(ap2.as_va_list(), 42i32); +} diff --git a/src/test/codegen/c-variadic-opt.rs b/src/test/codegen/c-variadic-opt.rs index 8594d309b0a5a..565e1c2f04858 100644 --- a/src/test/codegen/c-variadic-opt.rs +++ b/src/test/codegen/c-variadic-opt.rs @@ -14,6 +14,17 @@ extern "C" { #[no_mangle] pub unsafe extern "C" fn c_variadic_no_use(fmt: *const i8, mut ap: ...) -> i32 { // CHECK: call void @llvm.va_start - vprintf(fmt, ap) + vprintf(fmt, ap.as_va_list()) + // CHECK: call void @llvm.va_end +} + +// Check that `VaListImpl::clone` gets inlined into a direct call to `llvm.va_copy` +#[no_mangle] +pub unsafe extern "C" fn c_variadic_clone(fmt: *const i8, mut ap: ...) -> i32 { + // CHECK: call void @llvm.va_start + let mut ap2 = ap.clone(); + // CHECK: call void @llvm.va_copy + let res = vprintf(fmt, ap2.as_va_list()); + res // CHECK: call void @llvm.va_end } diff --git a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs index 163d50c4e4b4a..a0a5b141ec0e1 100644 --- a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs +++ b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs @@ -88,6 +88,6 @@ pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize { } #[no_mangle] -pub unsafe extern "C" fn check_varargs_2(_: c_int, mut ap: ...) -> usize { +pub unsafe extern "C" fn check_varargs_2(_: c_int, _ap: ...) -> usize { 0 } diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index 3539c8d6b72ad..fdb37b10a9767 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -1,8 +1,39 @@ // ignore-wasm32-bare no libc to test ffi with +#![feature(c_variadic)] + +use std::ffi::VaList; #[link(name = "rust_test_helpers", kind = "static")] extern { fn rust_interesting_average(_: u64, ...) -> f64; + fn rust_valist_interesting_average(_: u64, _: VaList) -> f64; +} + +pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 { + rust_valist_interesting_average(n, ap.as_va_list()) +} + +pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) { + let mut ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30); + + // Advance one pair in the copy before checking + let mut ap2 = ap.clone(); + let _ = ap2.arg::(); + let _ = ap2.arg::(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + + // Advance one pair in the original + let _ = ap.arg::(); + let _ = ap.arg::(); + + let mut ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + + let mut ap2 = ap.clone(); + let _ = ap2.arg::(); + let _ = ap2.arg::(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 70); } pub fn main() { @@ -35,4 +66,12 @@ pub fn main() { let x: unsafe extern fn(u64, ...) -> f64 = rust_interesting_average; call(x); } + + unsafe { + assert_eq!(test_valist_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30); + } + + unsafe { + test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64); + } } diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr index e16d15a98bf9d..695eba2a7ee40 100644 --- a/src/test/ui/c-variadic/variadic-ffi-1.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr @@ -29,7 +29,7 @@ LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo; | ^^^ expected non-variadic fn, found variadic function | = note: expected type `unsafe extern "C" fn(isize, u8)` - found type `for<'r> unsafe extern "C" fn(isize, u8, std::ffi::VaList<'r>, ...) {foo}` + found type `for<'r> unsafe extern "C" fn(isize, u8, std::ffi::VaListImpl<'r>, ...) {foo}` error[E0308]: mismatched types --> $DIR/variadic-ffi-1.rs:20:54 @@ -37,7 +37,7 @@ error[E0308]: mismatched types LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar; | ^^^ expected variadic fn, found non-variadic function | - = note: expected type `for<'r> extern "C" fn(isize, u8, std::ffi::VaList<'r>, ...)` + = note: expected type `for<'r> extern "C" fn(isize, u8, std::ffi::VaListImpl<'r>, ...)` found type `extern "C" fn(isize, u8) {bar}` error[E0617]: can't pass `f32` to variadic function diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr index a1afbb06390f8..3c5131835b572 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr @@ -1,16 +1,16 @@ error[E0621]: explicit lifetime required in the type of `ap` --> $DIR/variadic-ffi-4.rs:8:5 | -LL | pub unsafe extern "C" fn no_escape0<'a>(_: usize, ap: ...) -> VaList<'a> { - | --- help: add explicit lifetime `'a` to the type of `ap`: `core::ffi::VaList<'a>` +LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { + | --- help: add explicit lifetime `'f` to the type of `ap`: `core::ffi::VaListImpl<'f>` LL | ap - | ^^ lifetime `'a` required + | ^^ lifetime `'f` required error[E0621]: explicit lifetime required in the type of `ap` --> $DIR/variadic-ffi-4.rs:12:5 | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { - | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaList<'static>` +LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { + | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaListImpl<'static>` LL | ap | ^^ lifetime `'static` required @@ -20,43 +20,43 @@ error: lifetime may not live long enough LL | let _ = ap.with_copy(|ap| { ap }); | --- ^^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is core::ffi::VaList<'2> - | has type `core::ffi::VaList<'1>` + | | return type of closure is core::ffi::VaList<'2, '_> + | has type `core::ffi::VaList<'1, '_>` error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:20:5 | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaList<'1>` +LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'1>` | | - | has type `&mut core::ffi::VaList<'2>` + | has type `&mut core::ffi::VaListImpl<'2>` LL | *ap0 = ap1; - | ^^^^^^^^^^ assignment requires that `'1` must outlive `'2` + | ^^^^ assignment requires that `'1` must outlive `'2` error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:24:5 | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { - | --- ------- has type `core::ffi::VaList<'2>` +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { + | --- ------- has type `core::ffi::VaListImpl<'2>` | | - | has type `&mut core::ffi::VaList<'1>` + | has type `&mut core::ffi::VaListImpl<'1>` LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:24:5 | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { - | --- ------- has type `core::ffi::VaList<'1>` +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { + | --- ------- has type `core::ffi::VaListImpl<'1>` | | - | has type `&mut core::ffi::VaList<'2>` + | has type `&mut core::ffi::VaListImpl<'2>` LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` error[E0384]: cannot assign to immutable argument `ap0` --> $DIR/variadic-ffi-4.rs:24:5 | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { | --- help: make this binding mutable: `mut ap0` LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ cannot assign to immutable argument @@ -64,7 +64,7 @@ LL | ap0 = &mut ap1; error[E0597]: `ap1` does not live long enough --> $DIR/variadic-ffi-4.rs:24:11 | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { | - let's call the lifetime of this reference `'1` LL | ap0 = &mut ap1; | ------^^^^^^^^ @@ -73,9 +73,19 @@ LL | ap0 = &mut ap1; | assignment requires that `ap1` is borrowed for `'1` ... LL | } - | - `ap1` dropped here while still borrowed + | - `ap1` dropped here while still borrowed -error: aborting due to 8 previous errors +error: lifetime may not live long enough + --> $DIR/variadic-ffi-4.rs:32:5 + | +LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | ------- ------- has type `core::ffi::VaListImpl<'1>` + | | + | has type `&mut core::ffi::VaListImpl<'2>` +LL | *ap0 = ap1.clone(); + | ^^^^ assignment requires that `'1` must outlive `'2` + +error: aborting due to 9 previous errors Some errors have detailed explanations: E0384, E0597, E0621. For more information about an error, try `rustc --explain E0384`. diff --git a/src/test/ui/c-variadic/variadic-ffi-4.rs b/src/test/ui/c-variadic/variadic-ffi-4.rs index 1c77479d02f40..07c32ecbfc2dc 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.rs +++ b/src/test/ui/c-variadic/variadic-ffi-4.rs @@ -2,13 +2,13 @@ #![no_std] #![feature(c_variadic)] -use core::ffi::VaList; +use core::ffi::{VaList, VaListImpl}; -pub unsafe extern "C" fn no_escape0<'a>(_: usize, ap: ...) -> VaList<'a> { +pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { ap //~ ERROR: explicit lifetime required } -pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { +pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { ap //~ ERROR: explicit lifetime required } @@ -16,14 +16,18 @@ pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { let _ = ap.with_copy(|ap| { ap }); //~ ERROR: cannot infer an appropriate lifetime } -pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { +pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { *ap0 = ap1; //~ ERROR: mismatched types } -pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { ap0 = &mut ap1; - //~^ ERROR: a value of type `core::ffi::VaList<'_>` is borrowed for too long + //~^ ERROR: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long //~^^ ERROR: mismatched types //~^^^ ERROR: mismatched types //~^^^^ ERROR: cannot infer an appropriate lifetime } + +pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + *ap0 = ap1.clone(); //~ ERROR: cannot infer an appropriate lifetime +} diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr index 80b765671c5d0..72d4d8b63445a 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr @@ -1,16 +1,16 @@ error[E0621]: explicit lifetime required in the type of `ap` --> $DIR/variadic-ffi-4.rs:8:5 | -LL | pub unsafe extern "C" fn no_escape0<'a>(_: usize, ap: ...) -> VaList<'a> { - | --- help: add explicit lifetime `'a` to the type of `ap`: `core::ffi::VaList<'a>` +LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { + | --- help: add explicit lifetime `'f` to the type of `ap`: `core::ffi::VaListImpl<'f>` LL | ap - | ^^ lifetime `'a` required + | ^^ lifetime `'f` required error[E0621]: explicit lifetime required in the type of `ap` --> $DIR/variadic-ffi-4.rs:12:5 | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { - | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaList<'static>` +LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { + | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaListImpl<'static>` LL | ap | ^^ lifetime `'static` required @@ -26,14 +26,14 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th LL | let _ = ap.with_copy(|ap| { ap }); | ^^^^^^^^^^^ = note: ...so that the expression is assignable: - expected core::ffi::VaList<'_> - found core::ffi::VaList<'_> + expected core::ffi::VaList<'_, '_> + found core::ffi::VaList<'_, '_> note: but, the lifetime must be valid for the method call at 16:13... --> $DIR/variadic-ffi-4.rs:16:13 | LL | let _ = ap.with_copy(|ap| { ap }); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...so type `core::ffi::VaList<'_>` of expression is valid during the expression +note: ...so type `core::ffi::VaList<'_, '_>` of expression is valid during the expression --> $DIR/variadic-ffi-4.rs:16:13 | LL | let _ = ap.with_copy(|ap| { ap }); @@ -45,24 +45,24 @@ error[E0308]: mismatched types LL | *ap0 = ap1; | ^^^ lifetime mismatch | - = note: expected type `core::ffi::VaList<'_>` - found type `core::ffi::VaList<'_>` + = note: expected type `core::ffi::VaListImpl<'_>` + found type `core::ffi::VaListImpl<'_>` note: the anonymous lifetime #3 defined on the function body at 19:1... --> $DIR/variadic-ffi-4.rs:19:1 | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { LL | | *ap0 = ap1; LL | | } | |_^ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 19:1 --> $DIR/variadic-ffi-4.rs:19:1 | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { LL | | *ap0 = ap1; LL | | } | |_^ -error[E0490]: a value of type `core::ffi::VaList<'_>` is borrowed for too long +error[E0490]: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long --> $DIR/variadic-ffi-4.rs:24:11 | LL | ap0 = &mut ap1; @@ -71,7 +71,7 @@ LL | ap0 = &mut ap1; note: the type is valid for the anonymous lifetime #1 defined on the function body at 23:1 --> $DIR/variadic-ffi-4.rs:23:1 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | @@ -82,7 +82,7 @@ LL | | } note: but the borrow lasts for the anonymous lifetime #3 defined on the function body at 23:1 --> $DIR/variadic-ffi-4.rs:23:1 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | @@ -97,12 +97,12 @@ error[E0308]: mismatched types LL | ap0 = &mut ap1; | ^^^^^^^^ lifetime mismatch | - = note: expected type `&mut core::ffi::VaList<'_>` - found type `&mut core::ffi::VaList<'_>` + = note: expected type `&mut core::ffi::VaListImpl<'_>` + found type `&mut core::ffi::VaListImpl<'_>` note: the anonymous lifetime #3 defined on the function body at 23:1... --> $DIR/variadic-ffi-4.rs:23:1 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | @@ -113,7 +113,7 @@ LL | | } note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 23:1 --> $DIR/variadic-ffi-4.rs:23:1 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | @@ -128,12 +128,12 @@ error[E0308]: mismatched types LL | ap0 = &mut ap1; | ^^^^^^^^ lifetime mismatch | - = note: expected type `&mut core::ffi::VaList<'_>` - found type `&mut core::ffi::VaList<'_>` + = note: expected type `&mut core::ffi::VaListImpl<'_>` + found type `&mut core::ffi::VaListImpl<'_>` note: the anonymous lifetime #2 defined on the function body at 23:1... --> $DIR/variadic-ffi-4.rs:23:1 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | @@ -144,7 +144,7 @@ LL | | } note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 23:1 --> $DIR/variadic-ffi-4.rs:23:1 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | @@ -162,7 +162,7 @@ LL | ap0 = &mut ap1; note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 23:1... --> $DIR/variadic-ffi-4.rs:23:1 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | @@ -170,7 +170,7 @@ LL | | LL | | LL | | } | |_^ -note: ...so that the type `core::ffi::VaList<'_>` is not borrowed for too long +note: ...so that the type `core::ffi::VaListImpl<'_>` is not borrowed for too long --> $DIR/variadic-ffi-4.rs:24:11 | LL | ap0 = &mut ap1; @@ -178,7 +178,7 @@ LL | ap0 = &mut ap1; note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 23:1... --> $DIR/variadic-ffi-4.rs:23:1 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) { +LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | @@ -192,7 +192,34 @@ note: ...so that reference does not outlive borrowed content LL | ap0 = &mut ap1; | ^^^^^^^^ -error: aborting due to 8 previous errors +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/variadic-ffi-4.rs:32:16 + | +LL | *ap0 = ap1.clone(); + | ^^^^^ + | +note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 31:1... + --> $DIR/variadic-ffi-4.rs:31:1 + | +LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +LL | | *ap0 = ap1.clone(); +LL | | } + | |_^ + = note: ...so that the types are compatible: + expected &core::ffi::VaListImpl<'_> + found &core::ffi::VaListImpl<'_> +note: but, the lifetime must be valid for the anonymous lifetime #2 defined on the function body at 31:1... + --> $DIR/variadic-ffi-4.rs:31:1 + | +LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +LL | | *ap0 = ap1.clone(); +LL | | } + | |_^ + = note: ...so that the expression is assignable: + expected core::ffi::VaListImpl<'_> + found core::ffi::VaListImpl<'_> + +error: aborting due to 9 previous errors Some errors have detailed explanations: E0308, E0621. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/custom-derive/auxiliary/plugin.rs b/src/test/ui/custom-derive/auxiliary/plugin.rs deleted file mode 100644 index 5e500de607c1a..0000000000000 --- a/src/test/ui/custom-derive/auxiliary/plugin.rs +++ /dev/null @@ -1,28 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro_derive(Foo)] -pub fn derive_foo(input: TokenStream) -> TokenStream { - input -} - -#[proc_macro_derive(Bar)] -pub fn derive_bar(input: TokenStream) -> TokenStream { - panic!("lolnope"); -} - -#[proc_macro_derive(WithHelper, attributes(helper))] -pub fn with_helper(input: TokenStream) -> TokenStream { - TokenStream::new() -} - -#[proc_macro_attribute] -pub fn helper(_: TokenStream, input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/ui/custom-derive/derive-in-mod.rs b/src/test/ui/custom-derive/derive-in-mod.rs deleted file mode 100644 index 8478ff1a6ae6c..0000000000000 --- a/src/test/ui/custom-derive/derive-in-mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -// compile-pass -// aux-build:plugin.rs - -extern crate plugin; - -mod inner { - use plugin::WithHelper; - - #[derive(WithHelper)] - struct S; -} - -fn main() {} diff --git a/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.rs b/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.rs deleted file mode 100644 index ba072ba3568b7..0000000000000 --- a/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.rs +++ /dev/null @@ -1,12 +0,0 @@ -// aux-build:plugin.rs - -#[macro_use(WithHelper)] -extern crate plugin; - -use plugin::helper; - -#[derive(WithHelper)] -#[helper] //~ ERROR `helper` is ambiguous -struct S; - -fn main() {} diff --git a/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.stderr b/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.stderr deleted file mode 100644 index e83c291c9bfe4..0000000000000 --- a/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0659]: `helper` is ambiguous (derive helper attribute vs any other name) - --> $DIR/helper-attr-blocked-by-import-ambig.rs:9:3 - | -LL | #[helper] - | ^^^^^^ ambiguous name - | -note: `helper` could refer to the derive helper attribute defined here - --> $DIR/helper-attr-blocked-by-import-ambig.rs:8:10 - | -LL | #[derive(WithHelper)] - | ^^^^^^^^^^ -note: `helper` could also refer to the attribute macro imported here - --> $DIR/helper-attr-blocked-by-import-ambig.rs:6:5 - | -LL | use plugin::helper; - | ^^^^^^^^^^^^^^ - = help: use `crate::helper` to refer to this attribute macro unambiguously - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/custom-derive/helper-attr-blocked-by-import.rs b/src/test/ui/custom-derive/helper-attr-blocked-by-import.rs deleted file mode 100644 index abbf014f55337..0000000000000 --- a/src/test/ui/custom-derive/helper-attr-blocked-by-import.rs +++ /dev/null @@ -1,28 +0,0 @@ -// compile-pass -// aux-build:plugin.rs - -#[macro_use(WithHelper)] -extern crate plugin; - -use self::one::*; -use self::two::*; - -mod helper {} - -mod one { - use helper; - - #[derive(WithHelper)] - #[helper] - struct One; -} - -mod two { - use helper; - - #[derive(WithHelper)] - #[helper] - struct Two; -} - -fn main() {} diff --git a/src/test/ui/custom-derive/issue-36935.rs b/src/test/ui/custom-derive/issue-36935.rs deleted file mode 100644 index 7a5d19f771f3c..0000000000000 --- a/src/test/ui/custom-derive/issue-36935.rs +++ /dev/null @@ -1,12 +0,0 @@ -// aux-build:plugin.rs - - -#[macro_use] extern crate plugin; - -#[derive(Foo, Bar)] //~ ERROR proc-macro derive panicked -struct Baz { - a: i32, - b: i32, -} - -fn main() {} diff --git a/src/test/ui/custom-derive/issue-36935.stderr b/src/test/ui/custom-derive/issue-36935.stderr deleted file mode 100644 index 2875bc5fce99b..0000000000000 --- a/src/test/ui/custom-derive/issue-36935.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: proc-macro derive panicked - --> $DIR/issue-36935.rs:6:15 - | -LL | #[derive(Foo, Bar)] - | ^^^ - | - = help: message: lolnope - -error: aborting due to previous error - diff --git a/src/test/ui/error-codes/E0617.rs b/src/test/ui/error-codes/E0617.rs index 51f13c7dbd540..439c3db576864 100644 --- a/src/test/ui/error-codes/E0617.rs +++ b/src/test/ui/error-codes/E0617.rs @@ -22,7 +22,7 @@ fn main() { //~^ ERROR can't pass `u16` to variadic function //~| HELP cast the value to `c_uint` printf(::std::ptr::null(), printf); - //~^ ERROR can't pass `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaList<'r>, ...) {printf}` to variadic function - //~| HELP cast the value to `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaList<'r>, ...)` + //~^ ERROR can't pass `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...) {printf}` to variadic function + //~| HELP cast the value to `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...)` } } diff --git a/src/test/ui/error-codes/E0617.stderr b/src/test/ui/error-codes/E0617.stderr index 8387d5c7e93a5..d866320bbcdf7 100644 --- a/src/test/ui/error-codes/E0617.stderr +++ b/src/test/ui/error-codes/E0617.stderr @@ -28,15 +28,15 @@ error[E0617]: can't pass `u16` to variadic function LL | printf(::std::ptr::null(), 0u16); | ^^^^ help: cast the value to `c_uint`: `0u16 as c_uint` -error[E0617]: can't pass `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaList<'r>, ...) {printf}` to variadic function +error[E0617]: can't pass `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...) {printf}` to variadic function --> $DIR/E0617.rs:24:36 | LL | printf(::std::ptr::null(), printf); | ^^^^^^ -help: cast the value to `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaList<'r>, ...)` +help: cast the value to `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...)` | -LL | printf(::std::ptr::null(), printf as for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaList<'r>, ...)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | printf(::std::ptr::null(), printf as for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/impl-trait/hidden-lifetimes.rs b/src/test/ui/impl-trait/hidden-lifetimes.rs new file mode 100644 index 0000000000000..2ee004a37a6fc --- /dev/null +++ b/src/test/ui/impl-trait/hidden-lifetimes.rs @@ -0,0 +1,63 @@ +// Test to show what happens if we were not careful and allowed invariant +// lifetimes to escape though an impl trait. +// +// Specifically we swap a long lived and short lived reference, giving us a +// dangling pointer. + +use std::cell::RefCell; +use std::rc::Rc; + +trait Swap: Sized { + fn swap(self, other: Self); +} + +impl Swap for &mut T { + fn swap(self, other: Self) { + std::mem::swap(self, other); + } +} + +impl Swap for Rc> { + fn swap(self, other: Self) { + >::swap(&self, &other); + } +} + +// Here we are hiding `'b` making the caller believe that `&'a mut &'s T` and +// `&'a mut &'l T` are the same type. +fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { + //~^ ERROR hidden type + x +} + +fn dangle_ref() -> &'static [i32; 3] { + let mut res = &[4, 5, 6]; + let x = [1, 2, 3]; + hide_ref(&mut res).swap(hide_ref(&mut &x)); + res +} + +// Here we are hiding `'b` making the caller believe that `Rc>` +// and `Rc>` are the same type. +// +// This is different to the previous example because the concrete return type +// only has a single lifetime. +fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc>) -> impl Swap + 'a { + //~^ ERROR hidden type + x +} + +fn dangle_rc_refcell() -> &'static [i32; 3] { + let long = Rc::new(RefCell::new(&[4, 5, 6])); + let x = [1, 2, 3]; + let short = Rc::new(RefCell::new(&x)); + hide_rc_refcell(long.clone()).swap(hide_rc_refcell(short)); + let res: &'static [i32; 3] = *long.borrow(); + res +} + +fn main() { + // both will print nonsense values. + println!("{:?}", dangle_ref()); + println!("{:?}", dangle_rc_refcell()) +} diff --git a/src/test/ui/impl-trait/hidden-lifetimes.stderr b/src/test/ui/impl-trait/hidden-lifetimes.stderr new file mode 100644 index 0000000000000..650161753d1e5 --- /dev/null +++ b/src/test/ui/impl-trait/hidden-lifetimes.stderr @@ -0,0 +1,27 @@ +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/hidden-lifetimes.rs:28:54 + | +LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { + | ^^^^^^^^^^^^^^ + | +note: hidden type `&'a mut &'b T` captures the lifetime 'b as defined on the function body at 28:17 + --> $DIR/hidden-lifetimes.rs:28:17 + | +LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { + | ^^ + +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/hidden-lifetimes.rs:45:70 + | +LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc>) -> impl Swap + 'a { + | ^^^^^^^^^^^^^^ + | +note: hidden type `std::rc::Rc>` captures the lifetime 'b as defined on the function body at 45:24 + --> $DIR/hidden-lifetimes.rs:45:24 + | +LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc>) -> impl Swap + 'a { + | ^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/impl-trait/multiple-lifetimes.rs b/src/test/ui/impl-trait/multiple-lifetimes.rs new file mode 100644 index 0000000000000..8346542135bec --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes.rs @@ -0,0 +1,12 @@ +// Test that multiple liftimes are allowed in impl trait types. +// compile-pass + +trait X<'x>: Sized {} + +impl X<'_> for U {} + +fn multiple_lifeteimes<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl X<'b> + 'a { + x +} + +fn main() {} diff --git a/src/test/ui/proc-macro/attribute-order-restricted.rs b/src/test/ui/proc-macro/attribute-order-restricted.rs index 7b1eecd155865..a3d4d23450ca6 100644 --- a/src/test/ui/proc-macro/attribute-order-restricted.rs +++ b/src/test/ui/proc-macro/attribute-order-restricted.rs @@ -1,14 +1,14 @@ -// aux-build:attr_proc_macro.rs +// aux-build:test-macros.rs -extern crate attr_proc_macro; -use attr_proc_macro::*; +#[macro_use] +extern crate test_macros; -#[attr_proc_macro] // OK +#[identity_attr] // OK #[derive(Clone)] struct Before; #[derive(Clone)] -#[attr_proc_macro] //~ ERROR macro attributes must be placed before `#[derive]` +#[identity_attr] //~ ERROR macro attributes must be placed before `#[derive]` struct After; fn main() {} diff --git a/src/test/ui/proc-macro/attribute-order-restricted.stderr b/src/test/ui/proc-macro/attribute-order-restricted.stderr index 39db45cf569a7..9ca8a443e40fb 100644 --- a/src/test/ui/proc-macro/attribute-order-restricted.stderr +++ b/src/test/ui/proc-macro/attribute-order-restricted.stderr @@ -1,8 +1,8 @@ error: macro attributes must be placed before `#[derive]` --> $DIR/attribute-order-restricted.rs:11:1 | -LL | #[attr_proc_macro] - | ^^^^^^^^^^^^^^^^^^ +LL | #[identity_attr] + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/proc-macro/attribute-with-error.rs b/src/test/ui/proc-macro/attribute-with-error.rs index 2cced40830a74..aaa6c07dddbbd 100644 --- a/src/test/ui/proc-macro/attribute-with-error.rs +++ b/src/test/ui/proc-macro/attribute-with-error.rs @@ -1,12 +1,11 @@ -// aux-build:attribute-with-error.rs +// aux-build:test-macros.rs #![feature(custom_inner_attributes)] -extern crate attribute_with_error; +#[macro_use] +extern crate test_macros; -use attribute_with_error::foo; - -#[foo] +#[recollect_attr] fn test1() { let a: i32 = "foo"; //~^ ERROR: mismatched types @@ -15,13 +14,13 @@ fn test1() { } fn test2() { - #![foo] + #![recollect_attr] // FIXME: should have a type error here and assert it works but it doesn't } trait A { - // FIXME: should have a #[foo] attribute here and assert that it works + // FIXME: should have a #[recollect_attr] attribute here and assert that it works fn foo(&self) { let a: i32 = "foo"; //~^ ERROR: mismatched types @@ -31,13 +30,13 @@ trait A { struct B; impl A for B { - #[foo] + #[recollect_attr] fn foo(&self) { let a: i32 = "foo"; //~^ ERROR: mismatched types } } -#[foo] +#[recollect_attr] fn main() { } diff --git a/src/test/ui/proc-macro/attribute-with-error.stderr b/src/test/ui/proc-macro/attribute-with-error.stderr index c5970ab6baaf8..937d47ff08979 100644 --- a/src/test/ui/proc-macro/attribute-with-error.stderr +++ b/src/test/ui/proc-macro/attribute-with-error.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/attribute-with-error.rs:11:18 + --> $DIR/attribute-with-error.rs:10:18 | LL | let a: i32 = "foo"; | ^^^^^ expected i32, found reference @@ -8,7 +8,7 @@ LL | let a: i32 = "foo"; found type `&'static str` error[E0308]: mismatched types - --> $DIR/attribute-with-error.rs:13:18 + --> $DIR/attribute-with-error.rs:12:18 | LL | let b: i32 = "f'oo"; | ^^^^^^ expected i32, found reference @@ -17,7 +17,7 @@ LL | let b: i32 = "f'oo"; found type `&'static str` error[E0308]: mismatched types - --> $DIR/attribute-with-error.rs:26:22 + --> $DIR/attribute-with-error.rs:25:22 | LL | let a: i32 = "foo"; | ^^^^^ expected i32, found reference @@ -26,7 +26,7 @@ LL | let a: i32 = "foo"; found type `&'static str` error[E0308]: mismatched types - --> $DIR/attribute-with-error.rs:36:22 + --> $DIR/attribute-with-error.rs:35:22 | LL | let a: i32 = "foo"; | ^^^^^ expected i32, found reference diff --git a/src/test/ui/proc-macro/auxiliary/attr_proc_macro.rs b/src/test/ui/proc-macro/auxiliary/attr_proc_macro.rs deleted file mode 100644 index b1f54be6bac4b..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/attr_proc_macro.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro_attribute] -pub fn attr_proc_macro(_: TokenStream, input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/ui/proc-macro/auxiliary/attribute-with-error.rs b/src/test/ui/proc-macro/auxiliary/attribute-with-error.rs deleted file mode 100644 index c073be0031019..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/attribute-with-error.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro_attribute] -pub fn foo(_attr: TokenStream, input: TokenStream) -> TokenStream { - input.into_iter().collect() -} diff --git a/src/test/ui/proc-macro/auxiliary/bang_proc_macro.rs b/src/test/ui/proc-macro/auxiliary/bang_proc_macro.rs deleted file mode 100644 index 16f3b7640290d..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/bang_proc_macro.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro] -pub fn bang_proc_macro(input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/ui/proc-macro/auxiliary/derive-a-b.rs b/src/test/ui/proc-macro/auxiliary/derive-a-b.rs deleted file mode 100644 index 64d4e0f7b7ae5..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/derive-a-b.rs +++ /dev/null @@ -1,17 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; -use proc_macro::TokenStream; - -#[proc_macro_derive(A)] -pub fn derive_a(_: TokenStream) -> TokenStream { - "".parse().unwrap() -} - -#[proc_macro_derive(B)] -pub fn derive_b(_: TokenStream) -> TokenStream { - "".parse().unwrap() -} diff --git a/src/test/ui/proc-macro/auxiliary/derive-a.rs b/src/test/ui/proc-macro/auxiliary/derive-a.rs deleted file mode 100644 index c9d94aba9f756..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/derive-a.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro_derive(A)] -pub fn derive_a(input: TokenStream) -> TokenStream { - "".parse().unwrap() -} diff --git a/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs index 9912a89dafb3f..ab532da299224 100644 --- a/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs +++ b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs @@ -1,2 +1,2 @@ #[macro_export] -macro_rules! my_attr { () => () } +macro_rules! empty_helper { () => () } diff --git a/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed.rs b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed.rs deleted file mode 100644 index 5b5243dd60ee3..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed.rs +++ /dev/null @@ -1,12 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; -use proc_macro::*; - -#[proc_macro_derive(MyTrait, attributes(my_attr))] -pub fn foo(_: TokenStream) -> TokenStream { - TokenStream::new() -} diff --git a/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs deleted file mode 100644 index 6e0bdcba9c50f..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs +++ /dev/null @@ -1,17 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; -use proc_macro::*; - -#[proc_macro_attribute] -pub fn my_attr(_: TokenStream, input: TokenStream) -> TokenStream { - input -} - -#[proc_macro_derive(MyTrait, attributes(my_attr))] -pub fn derive(input: TokenStream) -> TokenStream { - TokenStream::new() -} diff --git a/src/test/ui/proc-macro/auxiliary/derive-panic.rs b/src/test/ui/proc-macro/auxiliary/derive-panic.rs deleted file mode 100644 index e2afa7affa302..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/derive-panic.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro_derive(A)] -pub fn derive_a(_input: TokenStream) -> TokenStream { - panic!("nope!"); -} diff --git a/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs b/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs index 8f15a2b975bf3..d5d393b5a6457 100644 --- a/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs +++ b/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs @@ -3,14 +3,14 @@ pub type S = u8; #[macro_export] macro_rules! external { () => { - dollar_crate::m! { + print_bang! { struct M($crate::S); } - #[dollar_crate::a] + #[print_attr] struct A($crate::S); - #[derive(dollar_crate::d)] + #[derive(Print)] struct D($crate::S); }; } diff --git a/src/test/ui/proc-macro/auxiliary/dollar-crate.rs b/src/test/ui/proc-macro/auxiliary/dollar-crate.rs deleted file mode 100644 index c5347d2e81a6b..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/dollar-crate.rs +++ /dev/null @@ -1,35 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; -use proc_macro::TokenStream; - -#[proc_macro] -pub fn m_empty(input: TokenStream) -> TokenStream { - println!("PROC MACRO INPUT (PRETTY-PRINTED): {}", input); - println!("PROC MACRO INPUT: {:#?}", input); - TokenStream::new() -} - -#[proc_macro] -pub fn m(input: TokenStream) -> TokenStream { - println!("PROC MACRO INPUT (PRETTY-PRINTED): {}", input); - println!("PROC MACRO INPUT: {:#?}", input); - input.into_iter().collect() -} - -#[proc_macro_attribute] -pub fn a(_args: TokenStream, input: TokenStream) -> TokenStream { - println!("ATTRIBUTE INPUT (PRETTY-PRINTED): {}", input); - println!("ATTRIBUTE INPUT: {:#?}", input); - input.into_iter().collect() -} - -#[proc_macro_derive(d)] -pub fn d(input: TokenStream) -> TokenStream { - println!("DERIVE INPUT (PRETTY-PRINTED): {}", input); - println!("DERIVE INPUT: {:#?}", input); - input.into_iter().collect() -} diff --git a/src/test/ui/proc-macro/auxiliary/issue-41211.rs b/src/test/ui/proc-macro/auxiliary/issue-41211.rs deleted file mode 100644 index db946e7f331ca..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/issue-41211.rs +++ /dev/null @@ -1,12 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; -use proc_macro::TokenStream; - -#[proc_macro_attribute] -pub fn emit_unchanged(_args: TokenStream, input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/ui/proc-macro/auxiliary/issue-53481.rs b/src/test/ui/proc-macro/auxiliary/issue-53481.rs deleted file mode 100644 index d9f290dec7ef9..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/issue-53481.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::*; - -#[proc_macro_derive(MyTrait, attributes(my_attr))] -pub fn foo(_: TokenStream) -> TokenStream { - TokenStream::new() -} diff --git a/src/test/ui/proc-macro/auxiliary/macro-brackets.rs b/src/test/ui/proc-macro/auxiliary/macro-brackets.rs deleted file mode 100644 index f2c62ab1b5ef0..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/macro-brackets.rs +++ /dev/null @@ -1,12 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; -use proc_macro::*; - -#[proc_macro_attribute] -pub fn doit(_: TokenStream, input: TokenStream) -> TokenStream { - input.into_iter().collect() -} diff --git a/src/test/ui/proc-macro/auxiliary/nested-item-spans.rs b/src/test/ui/proc-macro/auxiliary/nested-item-spans.rs deleted file mode 100644 index 8f720b4574dde..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/nested-item-spans.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::*; - -#[proc_macro_attribute] -pub fn foo(_: TokenStream, item: TokenStream) -> TokenStream { - item.into_iter().collect() -} diff --git a/src/test/ui/proc-macro/auxiliary/proc-macro-gates.rs b/src/test/ui/proc-macro/auxiliary/proc-macro-gates.rs deleted file mode 100644 index c7c7167eca0d5..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/proc-macro-gates.rs +++ /dev/null @@ -1,18 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::*; - -#[proc_macro] -pub fn m(a: TokenStream) -> TokenStream { - a -} - -#[proc_macro_attribute] -pub fn a(_a: TokenStream, b: TokenStream) -> TokenStream { - b -} diff --git a/src/test/ui/proc-macro/auxiliary/span-preservation.rs b/src/test/ui/proc-macro/auxiliary/span-preservation.rs deleted file mode 100644 index 33c7968104b72..0000000000000 --- a/src/test/ui/proc-macro/auxiliary/span-preservation.rs +++ /dev/null @@ -1,13 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro_attribute] -pub fn foo(_: TokenStream, input: TokenStream) -> TokenStream { - input.into_iter().collect() -} diff --git a/src/test/ui/proc-macro/auxiliary/test-macros.rs b/src/test/ui/proc-macro/auxiliary/test-macros.rs index 15fe3804f9b4f..27efa44f98032 100644 --- a/src/test/ui/proc-macro/auxiliary/test-macros.rs +++ b/src/test/ui/proc-macro/auxiliary/test-macros.rs @@ -1,26 +1,112 @@ // force-host // no-prefer-dynamic +// Proc macros commonly used by tests. +// `panic`/`print` -> `panic_bang`/`print_bang` to avoid conflicts with standard macros. + #![crate_type = "proc-macro"] extern crate proc_macro; - use proc_macro::TokenStream; +// Macro that return empty token stream. + +#[proc_macro] +pub fn empty(_: TokenStream) -> TokenStream { + TokenStream::new() +} + #[proc_macro_attribute] -pub fn nop_attr(_attr: TokenStream, input: TokenStream) -> TokenStream { - assert!(_attr.to_string().is_empty()); - input +pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_derive(Empty, attributes(empty_helper))] +pub fn empty_derive(_: TokenStream) -> TokenStream { + TokenStream::new() +} + +// Macro that panics. + +#[proc_macro] +pub fn panic_bang(_: TokenStream) -> TokenStream { + panic!("panic-bang"); } #[proc_macro_attribute] -pub fn no_output(_attr: TokenStream, _input: TokenStream) -> TokenStream { - assert!(_attr.to_string().is_empty()); - assert!(!_input.to_string().is_empty()); - "".parse().unwrap() +pub fn panic_attr(_: TokenStream, _: TokenStream) -> TokenStream { + panic!("panic-attr"); +} + +#[proc_macro_derive(Panic, attributes(panic_helper))] +pub fn panic_derive(_: TokenStream) -> TokenStream { + panic!("panic-derive"); } +// Macros that return the input stream. + #[proc_macro] -pub fn emit_input(input: TokenStream) -> TokenStream { +pub fn identity(input: TokenStream) -> TokenStream { input } + +#[proc_macro_attribute] +pub fn identity_attr(_: TokenStream, input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(Identity, attributes(identity_helper))] +pub fn identity_derive(input: TokenStream) -> TokenStream { + input +} + +// Macros that iterate and re-collect the input stream. + +#[proc_macro] +pub fn recollect(input: TokenStream) -> TokenStream { + input.into_iter().collect() +} + +#[proc_macro_attribute] +pub fn recollect_attr(_: TokenStream, input: TokenStream) -> TokenStream { + input.into_iter().collect() +} + +#[proc_macro_derive(Recollect, attributes(recollect_helper))] +pub fn recollect_derive(input: TokenStream) -> TokenStream { + input.into_iter().collect() +} + +// Macros that print their input in the original and re-collected forms (if they differ). + +fn print_helper(input: TokenStream, kind: &str) -> TokenStream { + let input_display = format!("{}", input); + let input_debug = format!("{:#?}", input); + let recollected = input.into_iter().collect(); + let recollected_display = format!("{}", recollected); + let recollected_debug = format!("{:#?}", recollected); + println!("PRINT-{} INPUT (DISPLAY): {}", kind, input_display); + if recollected_display != input_display { + println!("PRINT-{} RE-COLLECTED (DISPLAY): {}", kind, recollected_display); + } + println!("PRINT-{} INPUT (DEBUG): {}", kind, input_debug); + if recollected_debug != input_debug { + println!("PRINT-{} RE-COLLECTED (DEBUG): {}", kind, recollected_debug); + } + recollected +} + +#[proc_macro] +pub fn print_bang(input: TokenStream) -> TokenStream { + print_helper(input, "BANG") +} + +#[proc_macro_attribute] +pub fn print_attr(_: TokenStream, input: TokenStream) -> TokenStream { + print_helper(input, "ATTR") +} + +#[proc_macro_derive(Print, attributes(print_helper))] +pub fn print_derive(input: TokenStream) -> TokenStream { + print_helper(input, "DERIVE") +} diff --git a/src/test/ui/proc-macro/derive-helper-shadowed.rs b/src/test/ui/proc-macro/derive-helper-shadowed.rs index 792b54b3b945a..0388e647b58aa 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowed.rs +++ b/src/test/ui/proc-macro/derive-helper-shadowed.rs @@ -1,16 +1,16 @@ // compile-pass -// aux-build:derive-helper-shadowed.rs +// aux-build:test-macros.rs // aux-build:derive-helper-shadowed-2.rs #[macro_use] -extern crate derive_helper_shadowed; -#[macro_use(my_attr)] +extern crate test_macros; +#[macro_use(empty_helper)] extern crate derive_helper_shadowed_2; -macro_rules! my_attr { () => () } +macro_rules! empty_helper { () => () } -#[derive(MyTrait)] -#[my_attr] // OK +#[derive(Empty)] +#[empty_helper] // OK struct S; fn main() {} diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.rs b/src/test/ui/proc-macro/derive-helper-shadowing.rs index f6fe9f9fd8b30..cdc0d6da94695 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.rs +++ b/src/test/ui/proc-macro/derive-helper-shadowing.rs @@ -1,23 +1,25 @@ -// aux-build:derive-helper-shadowing.rs +// aux-build:test-macros.rs -extern crate derive_helper_shadowing; -use derive_helper_shadowing::*; +#[macro_use] +extern crate test_macros; -#[my_attr] //~ ERROR `my_attr` is ambiguous -#[derive(MyTrait)] +use test_macros::empty_attr as empty_helper; + +#[empty_helper] //~ ERROR `empty_helper` is ambiguous +#[derive(Empty)] struct S { // FIXME No ambiguity, attributes in non-macro positions are not resolved properly - #[my_attr] + #[empty_helper] field: [u8; { // FIXME No ambiguity, derive helpers are not put into scope for non-attributes - use my_attr; + use empty_helper; // FIXME No ambiguity, derive helpers are not put into scope for inner items - #[my_attr] + #[empty_helper] struct U; mod inner { - #[my_attr] //~ ERROR attribute `my_attr` is currently unknown + #[empty_helper] //~ ERROR attribute `empty_helper` is currently unknown struct V; } diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr index fb86cabf939c4..ed6d30516562d 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr @@ -1,29 +1,29 @@ -error[E0658]: The attribute `my_attr` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/derive-helper-shadowing.rs:20:15 +error[E0658]: The attribute `empty_helper` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/derive-helper-shadowing.rs:22:15 | -LL | #[my_attr] - | ^^^^^^^ +LL | #[empty_helper] + | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0659]: `my_attr` is ambiguous (derive helper attribute vs any other name) - --> $DIR/derive-helper-shadowing.rs:6:3 +error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name) + --> $DIR/derive-helper-shadowing.rs:8:3 | -LL | #[my_attr] - | ^^^^^^^ ambiguous name +LL | #[empty_helper] + | ^^^^^^^^^^^^ ambiguous name | -note: `my_attr` could refer to the derive helper attribute defined here - --> $DIR/derive-helper-shadowing.rs:7:10 +note: `empty_helper` could refer to the derive helper attribute defined here + --> $DIR/derive-helper-shadowing.rs:9:10 | -LL | #[derive(MyTrait)] - | ^^^^^^^ -note: `my_attr` could also refer to the attribute macro imported here - --> $DIR/derive-helper-shadowing.rs:4:5 +LL | #[derive(Empty)] + | ^^^^^ +note: `empty_helper` could also refer to the attribute macro imported here + --> $DIR/derive-helper-shadowing.rs:6:5 | -LL | use derive_helper_shadowing::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: use `crate::my_attr` to refer to this attribute macro unambiguously +LL | use test_macros::empty_attr as empty_helper; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `crate::empty_helper` to refer to this attribute macro unambiguously error: aborting due to 2 previous errors diff --git a/src/test/ui/proc-macro/derive-in-mod.rs b/src/test/ui/proc-macro/derive-in-mod.rs new file mode 100644 index 0000000000000..e6b91324f95d0 --- /dev/null +++ b/src/test/ui/proc-macro/derive-in-mod.rs @@ -0,0 +1,13 @@ +// compile-pass +// aux-build:test-macros.rs + +extern crate test_macros; + +mod inner { + use test_macros::Empty; + + #[derive(Empty)] + struct S; +} + +fn main() {} diff --git a/src/test/ui/proc-macro/derive-still-gated.rs b/src/test/ui/proc-macro/derive-still-gated.rs index 526eff39891ae..d895d26f26763 100644 --- a/src/test/ui/proc-macro/derive-still-gated.rs +++ b/src/test/ui/proc-macro/derive-still-gated.rs @@ -1,11 +1,9 @@ -// aux-build:derive-a.rs - -#![allow(warnings)] +// aux-build:test-macros.rs #[macro_use] -extern crate derive_a; +extern crate test_macros; -#[derive_A] //~ ERROR attribute `derive_A` is currently unknown +#[derive_Empty] //~ ERROR attribute `derive_Empty` is currently unknown struct A; fn main() {} diff --git a/src/test/ui/proc-macro/derive-still-gated.stderr b/src/test/ui/proc-macro/derive-still-gated.stderr index d235343ff1618..f299b5abdbc6b 100644 --- a/src/test/ui/proc-macro/derive-still-gated.stderr +++ b/src/test/ui/proc-macro/derive-still-gated.stderr @@ -1,8 +1,8 @@ -error[E0658]: The attribute `derive_A` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/derive-still-gated.rs:8:3 +error[E0658]: The attribute `derive_Empty` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/derive-still-gated.rs:6:3 | -LL | #[derive_A] - | ^^^^^^^^ help: a built-in attribute with a similar name exists: `derive` +LL | #[derive_Empty] + | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs index 2d54c07ff9530..2615db3e119f1 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs +++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs @@ -1,22 +1,23 @@ // compile-pass // edition:2018 -// aux-build:dollar-crate.rs +// aux-build:test-macros.rs // Anonymize unstable non-dummy spans while still showing dummy spans `0..0`. // normalize-stdout-test "bytes\([^0]\w*\.\.(\w+)\)" -> "bytes(LO..$1)" // normalize-stdout-test "bytes\((\w+)\.\.[^0]\w*\)" -> "bytes($1..HI)" -extern crate dollar_crate; +#[macro_use] +extern crate test_macros; type S = u8; macro_rules! m { () => { - dollar_crate::m_empty! { + print_bang! { struct M($crate::S); } - #[dollar_crate::a] + #[print_attr] struct A($crate::S); }; } diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout index 618380d7f0bee..0611fcb13f267 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout +++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout @@ -1,5 +1,5 @@ -PROC MACRO INPUT (PRETTY-PRINTED): struct M ( $crate :: S ) ; -PROC MACRO INPUT: TokenStream [ +PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ; +PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", span: #2 bytes(LO..HI), @@ -38,8 +38,9 @@ PROC MACRO INPUT: TokenStream [ span: #2 bytes(LO..HI), }, ] -ATTRIBUTE INPUT (PRETTY-PRINTED): struct A(crate::S); -ATTRIBUTE INPUT: TokenStream [ +PRINT-ATTR INPUT (DISPLAY): struct A(crate::S); +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", span: #2 bytes(LO..HI), diff --git a/src/test/ui/proc-macro/dollar-crate.rs b/src/test/ui/proc-macro/dollar-crate.rs index 1460e9a3b2d55..aadd87ffaf203 100644 --- a/src/test/ui/proc-macro/dollar-crate.rs +++ b/src/test/ui/proc-macro/dollar-crate.rs @@ -1,29 +1,28 @@ // edition:2018 -// aux-build:dollar-crate.rs +// aux-build:test-macros.rs // aux-build:dollar-crate-external.rs // Anonymize unstable non-dummy spans while still showing dummy spans `0..0`. // normalize-stdout-test "bytes\([^0]\w*\.\.(\w+)\)" -> "bytes(LO..$1)" // normalize-stdout-test "bytes\((\w+)\.\.[^0]\w*\)" -> "bytes($1..HI)" -extern crate dollar_crate; +#[macro_use] +extern crate test_macros; extern crate dollar_crate_external; type S = u8; mod local { - use crate::dollar_crate; - macro_rules! local { () => { - dollar_crate::m! { + print_bang! { struct M($crate::S); } - #[dollar_crate::a] + #[print_attr] struct A($crate::S); - #[derive(dollar_crate::d)] + #[derive(Print)] struct D($crate::S); //~ ERROR the name `D` is defined multiple times }; } diff --git a/src/test/ui/proc-macro/dollar-crate.stderr b/src/test/ui/proc-macro/dollar-crate.stderr index d1b836e7f6f28..5d78a8e198729 100644 --- a/src/test/ui/proc-macro/dollar-crate.stderr +++ b/src/test/ui/proc-macro/dollar-crate.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `D` is defined multiple times - --> $DIR/dollar-crate.rs:27:13 + --> $DIR/dollar-crate.rs:26:13 | LL | struct D($crate::S); | ^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | local!(); = note: `D` must be defined only once in the type namespace of this module error[E0428]: the name `D` is defined multiple times - --> $DIR/dollar-crate.rs:37:5 + --> $DIR/dollar-crate.rs:36:5 | LL | dollar_crate_external::external!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/proc-macro/dollar-crate.stdout b/src/test/ui/proc-macro/dollar-crate.stdout index 454da53943054..3c88ee99842a2 100644 --- a/src/test/ui/proc-macro/dollar-crate.stdout +++ b/src/test/ui/proc-macro/dollar-crate.stdout @@ -1,5 +1,5 @@ -PROC MACRO INPUT (PRETTY-PRINTED): struct M ( $crate :: S ) ; -PROC MACRO INPUT: TokenStream [ +PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ; +PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", span: #2 bytes(LO..HI), @@ -38,8 +38,9 @@ PROC MACRO INPUT: TokenStream [ span: #2 bytes(LO..HI), }, ] -ATTRIBUTE INPUT (PRETTY-PRINTED): struct A(crate::S); -ATTRIBUTE INPUT: TokenStream [ +PRINT-ATTR INPUT (DISPLAY): struct A(crate::S); +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", span: #2 bytes(LO..HI), @@ -78,8 +79,9 @@ ATTRIBUTE INPUT: TokenStream [ span: #2 bytes(LO..HI), }, ] -DERIVE INPUT (PRETTY-PRINTED): struct D(crate::S); -DERIVE INPUT: TokenStream [ +PRINT-DERIVE INPUT (DISPLAY): struct D(crate::S); +PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( $crate :: S ) ; +PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "struct", span: #2 bytes(LO..HI), @@ -118,8 +120,8 @@ DERIVE INPUT: TokenStream [ span: #2 bytes(LO..HI), }, ] -PROC MACRO INPUT (PRETTY-PRINTED): struct M ( $crate :: S ) ; -PROC MACRO INPUT: TokenStream [ +PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ; +PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", span: #10 bytes(LO..HI), @@ -158,8 +160,9 @@ PROC MACRO INPUT: TokenStream [ span: #10 bytes(LO..HI), }, ] -ATTRIBUTE INPUT (PRETTY-PRINTED): struct A(::dollar_crate_external::S); -ATTRIBUTE INPUT: TokenStream [ +PRINT-ATTR INPUT (DISPLAY): struct A(::dollar_crate_external::S); +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", span: #10 bytes(LO..HI), @@ -198,8 +201,9 @@ ATTRIBUTE INPUT: TokenStream [ span: #10 bytes(LO..HI), }, ] -DERIVE INPUT (PRETTY-PRINTED): struct D(::dollar_crate_external::S); -DERIVE INPUT: TokenStream [ +PRINT-DERIVE INPUT (DISPLAY): struct D(::dollar_crate_external::S); +PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( $crate :: S ) ; +PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "struct", span: #10 bytes(LO..HI), diff --git a/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs b/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs new file mode 100644 index 0000000000000..3a1c56efce8c2 --- /dev/null +++ b/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs @@ -0,0 +1,11 @@ +// aux-build:test-macros.rs + +#[macro_use(Empty)] +extern crate test_macros; +use test_macros::empty_attr as empty_helper; + +#[derive(Empty)] +#[empty_helper] //~ ERROR `empty_helper` is ambiguous +struct S; + +fn main() {} diff --git a/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr b/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr new file mode 100644 index 0000000000000..012fb105b128d --- /dev/null +++ b/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr @@ -0,0 +1,21 @@ +error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name) + --> $DIR/helper-attr-blocked-by-import-ambig.rs:8:3 + | +LL | #[empty_helper] + | ^^^^^^^^^^^^ ambiguous name + | +note: `empty_helper` could refer to the derive helper attribute defined here + --> $DIR/helper-attr-blocked-by-import-ambig.rs:7:10 + | +LL | #[derive(Empty)] + | ^^^^^ +note: `empty_helper` could also refer to the attribute macro imported here + --> $DIR/helper-attr-blocked-by-import-ambig.rs:5:5 + | +LL | use test_macros::empty_attr as empty_helper; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `crate::empty_helper` to refer to this attribute macro unambiguously + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs b/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs new file mode 100644 index 0000000000000..6d3e5ec198d85 --- /dev/null +++ b/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs @@ -0,0 +1,28 @@ +// compile-pass +// aux-build:test-macros.rs + +#[macro_use(Empty)] +extern crate test_macros; + +use self::one::*; +use self::two::*; + +mod empty_helper {} + +mod one { + use empty_helper; + + #[derive(Empty)] + #[empty_helper] + struct One; +} + +mod two { + use empty_helper; + + #[derive(Empty)] + #[empty_helper] + struct Two; +} + +fn main() {} diff --git a/src/test/ui/proc-macro/import.rs b/src/test/ui/proc-macro/import.rs index 8fbccdf1aed14..d1b1ff350695f 100644 --- a/src/test/ui/proc-macro/import.rs +++ b/src/test/ui/proc-macro/import.rs @@ -1,11 +1,8 @@ -// aux-build:derive-a.rs +// aux-build:test-macros.rs -#![allow(warnings)] +extern crate test_macros; -#[macro_use] -extern crate derive_a; - -use derive_a::derive_a; -//~^ ERROR: unresolved import `derive_a::derive_a` +use test_macros::empty_derive; +//~^ ERROR: unresolved import `test_macros::empty_derive` fn main() {} diff --git a/src/test/ui/proc-macro/import.stderr b/src/test/ui/proc-macro/import.stderr index 813a8ac260460..aae621193ab9f 100644 --- a/src/test/ui/proc-macro/import.stderr +++ b/src/test/ui/proc-macro/import.stderr @@ -1,8 +1,8 @@ -error[E0432]: unresolved import `derive_a::derive_a` - --> $DIR/import.rs:8:5 +error[E0432]: unresolved import `test_macros::empty_derive` + --> $DIR/import.rs:5:5 | -LL | use derive_a::derive_a; - | ^^^^^^^^^^^^^^^^^^ no `derive_a` in the root +LL | use test_macros::empty_derive; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `empty_derive` in the root error: aborting due to previous error diff --git a/src/test/ui/proc-macro/issue-36935.rs b/src/test/ui/proc-macro/issue-36935.rs new file mode 100644 index 0000000000000..f809592d5f449 --- /dev/null +++ b/src/test/ui/proc-macro/issue-36935.rs @@ -0,0 +1,12 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[derive(Identity, Panic)] //~ ERROR proc-macro derive panicked +struct Baz { + a: i32, + b: i32, +} + +fn main() {} diff --git a/src/test/ui/proc-macro/issue-36935.stderr b/src/test/ui/proc-macro/issue-36935.stderr new file mode 100644 index 0000000000000..da4366eb668d6 --- /dev/null +++ b/src/test/ui/proc-macro/issue-36935.stderr @@ -0,0 +1,10 @@ +error: proc-macro derive panicked + --> $DIR/issue-36935.rs:6:20 + | +LL | #[derive(Identity, Panic)] + | ^^^^^ + | + = help: message: panic-derive + +error: aborting due to previous error + diff --git a/src/test/ui/proc-macro/issue-37788.rs b/src/test/ui/proc-macro/issue-37788.rs index 75fcd24d85f6f..73b1f0d58c837 100644 --- a/src/test/ui/proc-macro/issue-37788.rs +++ b/src/test/ui/proc-macro/issue-37788.rs @@ -1,7 +1,7 @@ -// aux-build:derive-a-b.rs +// aux-build:test-macros.rs #[macro_use] -extern crate derive_a_b; +extern crate test_macros; fn main() { // Test that constructing the `visible_parent_map` (in `cstore_impl.rs`) does not ICE. diff --git a/src/test/ui/proc-macro/issue-41211.rs b/src/test/ui/proc-macro/issue-41211.rs index 0b082f4818f1b..ee9246e1c9b5c 100644 --- a/src/test/ui/proc-macro/issue-41211.rs +++ b/src/test/ui/proc-macro/issue-41211.rs @@ -1,14 +1,14 @@ -// aux-build:issue-41211.rs +// aux-build:test-macros.rs // FIXME: https://github.com/rust-lang/rust/issues/41430 // This is a temporary regression test for the ICE reported in #41211 #![feature(custom_inner_attributes)] -#![emit_unchanged] -//~^ ERROR attribute `emit_unchanged` is currently unknown to the compiler +#![identity_attr] +//~^ ERROR attribute `identity_attr` is currently unknown to the compiler //~| ERROR inconsistent resolution for a macro: first custom attribute, then attribute macro -extern crate issue_41211; -use issue_41211::emit_unchanged; +extern crate test_macros; +use test_macros::identity_attr; fn main() {} diff --git a/src/test/ui/proc-macro/issue-41211.stderr b/src/test/ui/proc-macro/issue-41211.stderr index dfb2f6f63d847..1de6b293ecfb8 100644 --- a/src/test/ui/proc-macro/issue-41211.stderr +++ b/src/test/ui/proc-macro/issue-41211.stderr @@ -1,8 +1,8 @@ -error[E0658]: The attribute `emit_unchanged` is currently unknown to the compiler and may have meaning added to it in the future +error[E0658]: The attribute `identity_attr` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/issue-41211.rs:8:4 | -LL | #![emit_unchanged] - | ^^^^^^^^^^^^^^ +LL | #![identity_attr] + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(custom_attribute)] to the crate attributes to enable @@ -10,8 +10,8 @@ LL | #![emit_unchanged] error: inconsistent resolution for a macro: first custom attribute, then attribute macro --> $DIR/issue-41211.rs:8:4 | -LL | #![emit_unchanged] - | ^^^^^^^^^^^^^^ +LL | #![identity_attr] + | ^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/proc-macro/issue-53481.rs b/src/test/ui/proc-macro/issue-53481.rs index 479fd1db630a3..2fbde5fedb95b 100644 --- a/src/test/ui/proc-macro/issue-53481.rs +++ b/src/test/ui/proc-macro/issue-53481.rs @@ -1,21 +1,21 @@ // compile-pass -// aux-build:issue-53481.rs +// aux-build:test-macros.rs #[macro_use] -extern crate issue_53481; +extern crate test_macros; mod m1 { - use m2::MyTrait; + use m2::Empty; - #[derive(MyTrait)] + #[derive(Empty)] struct A {} } mod m2 { - pub type MyTrait = u8; + pub type Empty = u8; - #[derive(MyTrait)] - #[my_attr] + #[derive(Empty)] + #[empty_helper] struct B {} } diff --git a/src/test/ui/proc-macro/load-panic.rs b/src/test/ui/proc-macro/load-panic.rs index fa279c559fbf1..2e9a311d882bd 100644 --- a/src/test/ui/proc-macro/load-panic.rs +++ b/src/test/ui/proc-macro/load-panic.rs @@ -1,10 +1,9 @@ -// aux-build:derive-panic.rs -// compile-flags:--error-format human +// aux-build:test-macros.rs #[macro_use] -extern crate derive_panic; +extern crate test_macros; -#[derive(A)] +#[derive(Panic)] //~^ ERROR: proc-macro derive panicked struct Foo; diff --git a/src/test/ui/proc-macro/load-panic.stderr b/src/test/ui/proc-macro/load-panic.stderr index b448c804bff59..40cc4ee0e3d37 100644 --- a/src/test/ui/proc-macro/load-panic.stderr +++ b/src/test/ui/proc-macro/load-panic.stderr @@ -1,10 +1,10 @@ error: proc-macro derive panicked - --> $DIR/load-panic.rs:7:10 + --> $DIR/load-panic.rs:6:10 | -LL | #[derive(A)] - | ^ +LL | #[derive(Panic)] + | ^^^^^ | - = help: message: nope! + = help: message: panic-derive error: aborting due to previous error diff --git a/src/test/ui/proc-macro/macro-brackets.rs b/src/test/ui/proc-macro/macro-brackets.rs index c46abf03654ce..aa0046f458229 100644 --- a/src/test/ui/proc-macro/macro-brackets.rs +++ b/src/test/ui/proc-macro/macro-brackets.rs @@ -1,13 +1,13 @@ -// aux-build:macro-brackets.rs +// aux-build:test-macros.rs -extern crate macro_brackets as bar; -use bar::doit; +#[macro_use] +extern crate test_macros; macro_rules! id { ($($t:tt)*) => ($($t)*) } -#[doit] +#[identity_attr] id![static X: u32 = 'a';]; //~ ERROR: mismatched types diff --git a/src/test/ui/proc-macro/macro-use-attr.rs b/src/test/ui/proc-macro/macro-use-attr.rs index 13db0725a388b..d1b1430fb5d03 100644 --- a/src/test/ui/proc-macro/macro-use-attr.rs +++ b/src/test/ui/proc-macro/macro-use-attr.rs @@ -1,9 +1,10 @@ // compile-pass -// aux-build:attr_proc_macro.rs +// aux-build:test-macros.rs -#[macro_use] extern crate attr_proc_macro; +#[macro_use] +extern crate test_macros; -#[attr_proc_macro] +#[identity_attr] struct Foo; fn main() { diff --git a/src/test/ui/proc-macro/macro-use-bang.rs b/src/test/ui/proc-macro/macro-use-bang.rs index 4bf3bcd6f3aae..d39c42267fb96 100644 --- a/src/test/ui/proc-macro/macro-use-bang.rs +++ b/src/test/ui/proc-macro/macro-use-bang.rs @@ -1,11 +1,11 @@ // compile-pass -// aux-build:bang_proc_macro.rs +// aux-build:test-macros.rs #![feature(proc_macro_hygiene)] #[macro_use] -extern crate bang_proc_macro; +extern crate test_macros; fn main() { - bang_proc_macro!(println!("Hello, world!")); + identity!(println!("Hello, world!")); } diff --git a/src/test/ui/proc-macro/macros-in-extern.rs b/src/test/ui/proc-macro/macros-in-extern.rs index 5c5603b6c06b0..0477b5c48ecc9 100644 --- a/src/test/ui/proc-macro/macros-in-extern.rs +++ b/src/test/ui/proc-macro/macros-in-extern.rs @@ -1,10 +1,9 @@ // aux-build:test-macros.rs // ignore-wasm32 +#[macro_use] extern crate test_macros; -use test_macros::{nop_attr, no_output, emit_input}; - fn main() { assert_eq!(unsafe { rust_get_test_int() }, 0isize); assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEF); @@ -12,14 +11,14 @@ fn main() { #[link(name = "rust_test_helpers", kind = "static")] extern { - #[no_output] + #[empty_attr] //~^ ERROR macro invocations in `extern {}` blocks are experimental fn some_definitely_unknown_symbol_which_should_be_removed(); - #[nop_attr] + #[identity_attr] //~^ ERROR macro invocations in `extern {}` blocks are experimental fn rust_get_test_int() -> isize; - emit_input!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;); + identity!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;); //~^ ERROR macro invocations in `extern {}` blocks are experimental } diff --git a/src/test/ui/proc-macro/macros-in-extern.stderr b/src/test/ui/proc-macro/macros-in-extern.stderr index 61571650f2f04..592c91553aa8c 100644 --- a/src/test/ui/proc-macro/macros-in-extern.stderr +++ b/src/test/ui/proc-macro/macros-in-extern.stderr @@ -1,26 +1,26 @@ error[E0658]: macro invocations in `extern {}` blocks are experimental - --> $DIR/macros-in-extern.rs:15:5 + --> $DIR/macros-in-extern.rs:14:5 | -LL | #[no_output] - | ^^^^^^^^^^^^ +LL | #[empty_attr] + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 = help: add #![feature(macros_in_extern)] to the crate attributes to enable error[E0658]: macro invocations in `extern {}` blocks are experimental - --> $DIR/macros-in-extern.rs:19:5 + --> $DIR/macros-in-extern.rs:18:5 | -LL | #[nop_attr] - | ^^^^^^^^^^^ +LL | #[identity_attr] + | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 = help: add #![feature(macros_in_extern)] to the crate attributes to enable error[E0658]: macro invocations in `extern {}` blocks are experimental - --> $DIR/macros-in-extern.rs:23:5 + --> $DIR/macros-in-extern.rs:22:5 | -LL | emit_input!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | identity!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/49476 = help: add #![feature(macros_in_extern)] to the crate attributes to enable diff --git a/src/test/ui/proc-macro/nested-item-spans.rs b/src/test/ui/proc-macro/nested-item-spans.rs index e365b74b3be8f..63da170d0bbb2 100644 --- a/src/test/ui/proc-macro/nested-item-spans.rs +++ b/src/test/ui/proc-macro/nested-item-spans.rs @@ -1,10 +1,9 @@ -// aux-build:nested-item-spans.rs +// aux-build:test-macros.rs -extern crate nested_item_spans; +#[macro_use] +extern crate test_macros; -use nested_item_spans::foo; - -#[foo] +#[recollect_attr] fn another() { fn bar() { let x: u32 = "x"; //~ ERROR: mismatched types @@ -14,7 +13,7 @@ fn another() { } fn main() { - #[foo] + #[recollect_attr] fn bar() { let x: u32 = "x"; //~ ERROR: mismatched types } diff --git a/src/test/ui/proc-macro/nested-item-spans.stderr b/src/test/ui/proc-macro/nested-item-spans.stderr index 011a91d446295..bef80311f38e5 100644 --- a/src/test/ui/proc-macro/nested-item-spans.stderr +++ b/src/test/ui/proc-macro/nested-item-spans.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/nested-item-spans.rs:10:22 + --> $DIR/nested-item-spans.rs:9:22 | LL | let x: u32 = "x"; | ^^^ expected u32, found reference @@ -8,7 +8,7 @@ LL | let x: u32 = "x"; found type `&'static str` error[E0308]: mismatched types - --> $DIR/nested-item-spans.rs:19:22 + --> $DIR/nested-item-spans.rs:18:22 | LL | let x: u32 = "x"; | ^^^ expected u32, found reference diff --git a/src/test/ui/proc-macro/no-macro-use-attr.rs b/src/test/ui/proc-macro/no-macro-use-attr.rs index 62a501ded1006..15ab431fe754a 100644 --- a/src/test/ui/proc-macro/no-macro-use-attr.rs +++ b/src/test/ui/proc-macro/no-macro-use-attr.rs @@ -1,9 +1,9 @@ -// aux-build:derive-a.rs +// aux-build:test-macros.rs #![feature(rustc_attrs)] #![warn(unused_extern_crates)] -extern crate derive_a; +extern crate test_macros; //~^ WARN unused extern crate #[rustc_error] diff --git a/src/test/ui/proc-macro/no-macro-use-attr.stderr b/src/test/ui/proc-macro/no-macro-use-attr.stderr index 4b2fce7f6e4ca..87487bcc7d662 100644 --- a/src/test/ui/proc-macro/no-macro-use-attr.stderr +++ b/src/test/ui/proc-macro/no-macro-use-attr.stderr @@ -1,8 +1,8 @@ warning: unused extern crate --> $DIR/no-macro-use-attr.rs:6:1 | -LL | extern crate derive_a; - | ^^^^^^^^^^^^^^^^^^^^^^ help: remove it +LL | extern crate test_macros; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | note: lint level defined here --> $DIR/no-macro-use-attr.rs:4:9 diff --git a/src/test/ui/proc-macro/proc-macro-gates.rs b/src/test/ui/proc-macro/proc-macro-gates.rs index af6bfa08aaa94..678dc83b753b5 100644 --- a/src/test/ui/proc-macro/proc-macro-gates.rs +++ b/src/test/ui/proc-macro/proc-macro-gates.rs @@ -1,61 +1,62 @@ -// aux-build:proc-macro-gates.rs +// aux-build:test-macros.rs // gate-test-proc_macro_hygiene #![feature(stmt_expr_attributes)] -extern crate proc_macro_gates as foo; - -use foo::*; +#[macro_use] +extern crate test_macros; fn _test_inner() { - #![a] //~ ERROR: non-builtin inner attributes are unstable + #![empty_attr] //~ ERROR: non-builtin inner attributes are unstable } -#[a] //~ ERROR: custom attributes cannot be applied to modules +#[empty_attr] //~ ERROR: custom attributes cannot be applied to modules mod _test2 {} mod _test2_inner { - #![a] //~ ERROR: custom attributes cannot be applied to modules + #![empty_attr] //~ ERROR: custom attributes cannot be applied to modules //~| ERROR: non-builtin inner attributes are unstable } -#[a = "y"] //~ ERROR: must only be followed by a delimiter token +#[empty_attr = "y"] //~ ERROR: must only be followed by a delimiter token fn _test3() {} fn attrs() { // Statement, item - #[a] // OK + #[empty_attr] // OK struct S; // Statement, macro - #[a] //~ ERROR: custom attributes cannot be applied to statements + #[empty_attr] //~ ERROR: custom attributes cannot be applied to statements println!(); // Statement, semi - #[a] //~ ERROR: custom attributes cannot be applied to statements + #[empty_attr] //~ ERROR: custom attributes cannot be applied to statements S; // Statement, local - #[a] //~ ERROR: custom attributes cannot be applied to statements + #[empty_attr] //~ ERROR: custom attributes cannot be applied to statements let _x = 2; // Expr - let _x = #[a] 2; //~ ERROR: custom attributes cannot be applied to expressions + let _x = #[identity_attr] 2; //~ ERROR: custom attributes cannot be applied to expressions // Opt expr - let _x = [#[a] 2]; //~ ERROR: custom attributes cannot be applied to expressions + let _x = [#[identity_attr] 2]; //~ ERROR: custom attributes cannot be applied to expressions // Expr macro - let _x = #[a] println!(); //~ ERROR: custom attributes cannot be applied to expressions + let _x = #[identity_attr] println!(); + //~^ ERROR: custom attributes cannot be applied to expressions } fn main() { - let _x: m!(u32) = 3; //~ ERROR: procedural macros cannot be expanded to types - if let m!(Some(_x)) = Some(3) {} //~ ERROR: procedural macros cannot be expanded to patterns + let _x: identity!(u32) = 3; //~ ERROR: procedural macros cannot be expanded to types + if let identity!(Some(_x)) = Some(3) {} + //~^ ERROR: procedural macros cannot be expanded to patterns - m!(struct S;); //~ ERROR: procedural macros cannot be expanded to statements - m!(let _x = 3;); //~ ERROR: procedural macros cannot be expanded to statements + empty!(struct S;); //~ ERROR: procedural macros cannot be expanded to statements + empty!(let _x = 3;); //~ ERROR: procedural macros cannot be expanded to statements - let _x = m!(3); //~ ERROR: procedural macros cannot be expanded to expressions - let _x = [m!(3)]; //~ ERROR: procedural macros cannot be expanded to expressions + let _x = identity!(3); //~ ERROR: procedural macros cannot be expanded to expressions + let _x = [empty!(3)]; //~ ERROR: procedural macros cannot be expanded to expressions } diff --git a/src/test/ui/proc-macro/proc-macro-gates.stderr b/src/test/ui/proc-macro/proc-macro-gates.stderr index 1bb864b52ea7d..f53ad222a0368 100644 --- a/src/test/ui/proc-macro/proc-macro-gates.stderr +++ b/src/test/ui/proc-macro/proc-macro-gates.stderr @@ -1,95 +1,95 @@ error[E0658]: non-builtin inner attributes are unstable - --> $DIR/proc-macro-gates.rs:11:5 + --> $DIR/proc-macro-gates.rs:10:5 | -LL | #![a] - | ^^^^^ +LL | #![empty_attr] + | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54726 = help: add #![feature(custom_inner_attributes)] to the crate attributes to enable error[E0658]: non-builtin inner attributes are unstable - --> $DIR/proc-macro-gates.rs:18:5 + --> $DIR/proc-macro-gates.rs:17:5 | -LL | #![a] - | ^^^^^ +LL | #![empty_attr] + | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54726 = help: add #![feature(custom_inner_attributes)] to the crate attributes to enable error[E0658]: custom attributes cannot be applied to modules - --> $DIR/proc-macro-gates.rs:14:1 + --> $DIR/proc-macro-gates.rs:13:1 | -LL | #[a] - | ^^^^ +LL | #[empty_attr] + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: custom attributes cannot be applied to modules - --> $DIR/proc-macro-gates.rs:18:5 + --> $DIR/proc-macro-gates.rs:17:5 | -LL | #![a] - | ^^^^^ +LL | #![empty_attr] + | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error: custom attribute invocations must be of the form #[foo] or #[foo(..)], the macro name must only be followed by a delimiter token - --> $DIR/proc-macro-gates.rs:22:1 + --> $DIR/proc-macro-gates.rs:21:1 | -LL | #[a = "y"] - | ^^^^^^^^^^ +LL | #[empty_attr = "y"] + | ^^^^^^^^^^^^^^^^^^^ error[E0658]: custom attributes cannot be applied to statements - --> $DIR/proc-macro-gates.rs:31:5 + --> $DIR/proc-macro-gates.rs:30:5 | -LL | #[a] - | ^^^^ +LL | #[empty_attr] + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: custom attributes cannot be applied to statements - --> $DIR/proc-macro-gates.rs:35:5 + --> $DIR/proc-macro-gates.rs:34:5 | -LL | #[a] - | ^^^^ +LL | #[empty_attr] + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: custom attributes cannot be applied to statements - --> $DIR/proc-macro-gates.rs:39:5 + --> $DIR/proc-macro-gates.rs:38:5 | -LL | #[a] - | ^^^^ +LL | #[empty_attr] + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: custom attributes cannot be applied to expressions - --> $DIR/proc-macro-gates.rs:43:14 + --> $DIR/proc-macro-gates.rs:42:14 | -LL | let _x = #[a] 2; - | ^^^^ +LL | let _x = #[identity_attr] 2; + | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: custom attributes cannot be applied to expressions - --> $DIR/proc-macro-gates.rs:46:15 + --> $DIR/proc-macro-gates.rs:45:15 | -LL | let _x = [#[a] 2]; - | ^^^^ +LL | let _x = [#[identity_attr] 2]; + | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: custom attributes cannot be applied to expressions - --> $DIR/proc-macro-gates.rs:49:14 + --> $DIR/proc-macro-gates.rs:48:14 | -LL | let _x = #[a] println!(); - | ^^^^ +LL | let _x = #[identity_attr] println!(); + | ^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable @@ -97,8 +97,8 @@ LL | let _x = #[a] println!(); error[E0658]: procedural macros cannot be expanded to types --> $DIR/proc-macro-gates.rs:53:13 | -LL | let _x: m!(u32) = 3; - | ^^^^^^^ +LL | let _x: identity!(u32) = 3; + | ^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable @@ -106,44 +106,44 @@ LL | let _x: m!(u32) = 3; error[E0658]: procedural macros cannot be expanded to patterns --> $DIR/proc-macro-gates.rs:54:12 | -LL | if let m!(Some(_x)) = Some(3) {} - | ^^^^^^^^^^^^ +LL | if let identity!(Some(_x)) = Some(3) {} + | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to statements - --> $DIR/proc-macro-gates.rs:56:5 + --> $DIR/proc-macro-gates.rs:57:5 | -LL | m!(struct S;); - | ^^^^^^^^^^^^^^ +LL | empty!(struct S;); + | ^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to statements - --> $DIR/proc-macro-gates.rs:57:5 + --> $DIR/proc-macro-gates.rs:58:5 | -LL | m!(let _x = 3;); - | ^^^^^^^^^^^^^^^^ +LL | empty!(let _x = 3;); + | ^^^^^^^^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to expressions - --> $DIR/proc-macro-gates.rs:59:14 + --> $DIR/proc-macro-gates.rs:60:14 | -LL | let _x = m!(3); - | ^^^^^ +LL | let _x = identity!(3); + | ^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable error[E0658]: procedural macros cannot be expanded to expressions - --> $DIR/proc-macro-gates.rs:60:15 + --> $DIR/proc-macro-gates.rs:61:15 | -LL | let _x = [m!(3)]; - | ^^^^^ +LL | let _x = [empty!(3)]; + | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/54727 = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable diff --git a/src/test/ui/proc-macro/proc-macro-gates2.rs b/src/test/ui/proc-macro/proc-macro-gates2.rs index 46b543a397cc7..35d7fc8042a3d 100644 --- a/src/test/ui/proc-macro/proc-macro-gates2.rs +++ b/src/test/ui/proc-macro/proc-macro-gates2.rs @@ -1,21 +1,20 @@ -// aux-build:proc-macro-gates.rs +// aux-build:test-macros.rs #![feature(stmt_expr_attributes)] -extern crate proc_macro_gates as foo; - -use foo::*; +#[macro_use] +extern crate test_macros; // NB. these errors aren't the best errors right now, but they're definitely // intended to be errors. Somehow using a custom attribute in these positions // should either require a feature gate or not be allowed on stable. -fn _test6<#[a] T>() {} +fn _test6<#[empty_attr] T>() {} //~^ ERROR: unknown to the compiler fn _test7() { match 1 { - #[a] //~ ERROR: unknown to the compiler + #[empty_attr] //~ ERROR: unknown to the compiler 0 => {} _ => {} } diff --git a/src/test/ui/proc-macro/proc-macro-gates2.stderr b/src/test/ui/proc-macro/proc-macro-gates2.stderr index 0e8236f460f8c..8eeca99ab3984 100644 --- a/src/test/ui/proc-macro/proc-macro-gates2.stderr +++ b/src/test/ui/proc-macro/proc-macro-gates2.stderr @@ -1,17 +1,17 @@ -error[E0658]: The attribute `a` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/proc-macro-gates2.rs:13:11 +error[E0658]: The attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-gates2.rs:12:11 | -LL | fn _test6<#[a] T>() {} - | ^^^^ +LL | fn _test6<#[empty_attr] T>() {} + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(custom_attribute)] to the crate attributes to enable -error[E0658]: The attribute `a` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/proc-macro-gates2.rs:18:9 +error[E0658]: The attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/proc-macro-gates2.rs:17:9 | -LL | #[a] - | ^^^^ +LL | #[empty_attr] + | ^^^^^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/proc-macro/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs index bb242f302496e..82607136f0b6f 100644 --- a/src/test/ui/proc-macro/resolve-error.rs +++ b/src/test/ui/proc-macro/resolve-error.rs @@ -1,7 +1,6 @@ // aux-build:derive-foo.rs // aux-build:derive-clona.rs -// aux-build:attr_proc_macro.rs -// aux-build:bang_proc_macro.rs +// aux-build:test-macros.rs #![feature(custom_attribute)] @@ -9,11 +8,10 @@ extern crate derive_foo; #[macro_use] extern crate derive_clona; -extern crate attr_proc_macro; -extern crate bang_proc_macro; +extern crate test_macros; -use attr_proc_macro::attr_proc_macro; -use bang_proc_macro::bang_proc_macro; +use test_macros::empty as bang_proc_macro; +use test_macros::empty_attr as attr_proc_macro; macro_rules! FooWithLongNam { () => {} diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr index cf7de578c7d42..705ef6006a049 100644 --- a/src/test/ui/proc-macro/resolve-error.stderr +++ b/src/test/ui/proc-macro/resolve-error.stderr @@ -1,47 +1,47 @@ error: cannot find derive macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:26:10 + --> $DIR/resolve-error.rs:24:10 | LL | #[derive(FooWithLongNan)] | ^^^^^^^^^^^^^^ help: try: `FooWithLongName` error: cannot find derive macro `Dlone` in this scope - --> $DIR/resolve-error.rs:36:10 + --> $DIR/resolve-error.rs:34:10 | LL | #[derive(Dlone)] | ^^^^^ help: try: `Clone` error: cannot find derive macro `Dlona` in this scope - --> $DIR/resolve-error.rs:40:10 + --> $DIR/resolve-error.rs:38:10 | LL | #[derive(Dlona)] | ^^^^^ help: try: `Clona` error: cannot find derive macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:44:10 + --> $DIR/resolve-error.rs:42:10 | LL | #[derive(attr_proc_macra)] | ^^^^^^^^^^^^^^^ error: cannot find macro `FooWithLongNama!` in this scope - --> $DIR/resolve-error.rs:49:5 + --> $DIR/resolve-error.rs:47:5 | LL | FooWithLongNama!(); | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam` error: cannot find macro `attr_proc_macra!` in this scope - --> $DIR/resolve-error.rs:52:5 + --> $DIR/resolve-error.rs:50:5 | LL | attr_proc_macra!(); | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac` error: cannot find macro `Dlona!` in this scope - --> $DIR/resolve-error.rs:55:5 + --> $DIR/resolve-error.rs:53:5 | LL | Dlona!(); | ^^^^^ error: cannot find macro `bang_proc_macrp!` in this scope - --> $DIR/resolve-error.rs:58:5 + --> $DIR/resolve-error.rs:56:5 | LL | bang_proc_macrp!(); | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro` diff --git a/src/test/ui/proc-macro/shadow.rs b/src/test/ui/proc-macro/shadow.rs index 9c49bae28a3bc..61959594c7981 100644 --- a/src/test/ui/proc-macro/shadow.rs +++ b/src/test/ui/proc-macro/shadow.rs @@ -1,8 +1,8 @@ -// aux-build:derive-a.rs +// aux-build:test-macros.rs #[macro_use] -extern crate derive_a; +extern crate test_macros; #[macro_use] -extern crate derive_a; //~ ERROR the name `derive_a` is defined multiple times +extern crate test_macros; //~ ERROR the name `test_macros` is defined multiple times fn main() {} diff --git a/src/test/ui/proc-macro/shadow.stderr b/src/test/ui/proc-macro/shadow.stderr index 08057e163496d..e7d95cc835811 100644 --- a/src/test/ui/proc-macro/shadow.stderr +++ b/src/test/ui/proc-macro/shadow.stderr @@ -1,13 +1,13 @@ -error[E0259]: the name `derive_a` is defined multiple times +error[E0259]: the name `test_macros` is defined multiple times --> $DIR/shadow.rs:6:1 | -LL | extern crate derive_a; - | ---------------------- previous import of the extern crate `derive_a` here +LL | extern crate test_macros; + | ------------------------- previous import of the extern crate `test_macros` here LL | #[macro_use] -LL | extern crate derive_a; - | ^^^^^^^^^^^^^^^^^^^^^^ `derive_a` reimported here +LL | extern crate test_macros; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `test_macros` reimported here | - = note: `derive_a` must be defined only once in the type namespace of this module + = note: `test_macros` must be defined only once in the type namespace of this module error: aborting due to previous error diff --git a/src/test/ui/proc-macro/span-preservation.rs b/src/test/ui/proc-macro/span-preservation.rs index 64f675ecc1c4d..0a82d28e9e544 100644 --- a/src/test/ui/proc-macro/span-preservation.rs +++ b/src/test/ui/proc-macro/span-preservation.rs @@ -1,19 +1,18 @@ //~ ERROR mismatched types -// aux-build:span-preservation.rs +// aux-build:test-macros.rs // For each of these, we should get the appropriate type mismatch error message, // and the function should be echoed. -extern crate span_preservation as foo; +#[macro_use] +extern crate test_macros; -use foo::foo; - -#[foo] +#[recollect_attr] fn a() { let x: usize = "hello";;;;; //~ ERROR mismatched types } -#[foo] +#[recollect_attr] fn b(x: Option) -> usize { match x { Some(x) => { return x }, //~ ERROR mismatched types @@ -21,7 +20,7 @@ fn b(x: Option) -> usize { } } -#[foo] +#[recollect_attr] fn c() { struct Foo { a: usize @@ -39,12 +38,12 @@ fn c() { // FIXME: This doesn't work at the moment. See the one below. The pretty-printer // injects a "C" between `extern` and `fn` which causes a "probably_eq" // `TokenStream` mismatch. The lack of `"C"` should be preserved in the AST. -#[foo] +#[recollect_attr] extern fn bar() { 0 } -#[foo] +#[recollect_attr] extern "C" fn baz() { 0 //~ ERROR mismatched types } diff --git a/src/test/ui/proc-macro/span-preservation.stderr b/src/test/ui/proc-macro/span-preservation.stderr index 1cc7706ce3a4c..cf03deee7e445 100644 --- a/src/test/ui/proc-macro/span-preservation.stderr +++ b/src/test/ui/proc-macro/span-preservation.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types found type `{integer}` error[E0308]: mismatched types - --> $DIR/span-preservation.rs:13:20 + --> $DIR/span-preservation.rs:12:20 | LL | let x: usize = "hello";;;;; | ^^^^^^^ expected usize, found reference @@ -13,7 +13,7 @@ LL | let x: usize = "hello";;;;; found type `&'static str` error[E0308]: mismatched types - --> $DIR/span-preservation.rs:19:29 + --> $DIR/span-preservation.rs:18:29 | LL | fn b(x: Option) -> usize { | ----- expected `usize` because of return type @@ -22,13 +22,13 @@ LL | Some(x) => { return x }, | ^ expected usize, found isize error[E0308]: mismatched types - --> $DIR/span-preservation.rs:35:22 + --> $DIR/span-preservation.rs:34:22 | LL | let x = Foo { a: 10isize }; | ^^^^^^^ expected usize, found isize error[E0560]: struct `c::Foo` has no field named `b` - --> $DIR/span-preservation.rs:36:26 + --> $DIR/span-preservation.rs:35:26 | LL | let y = Foo { a: 10, b: 10isize }; | ^ `c::Foo` does not have this field @@ -36,7 +36,7 @@ LL | let y = Foo { a: 10, b: 10isize }; = note: available fields are: `a` error[E0308]: mismatched types - --> $DIR/span-preservation.rs:49:5 + --> $DIR/span-preservation.rs:48:5 | LL | extern "C" fn baz() { | - possibly return type missing here?