diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 8da705e0cb06d..489259d1a6bc6 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -567,7 +567,7 @@ pub mod intrinsics { pub fn copy(src: *const T, dst: *mut T, count: usize); pub fn transmute(e: T) -> U; pub fn ctlz_nonzero(x: T) -> T; - pub fn needs_drop() -> bool; + pub fn needs_drop() -> bool; pub fn bitreverse(x: T) -> T; pub fn bswap(x: T) -> T; pub fn write_bytes(dst: *mut T, val: u8, count: usize); diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index 85ca908d0a266..0f1245c2758ed 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs @@ -55,6 +55,11 @@ struct NoisyDrop { inner: NoisyDropInner, } +struct NoisyDropUnsized { + inner: NoisyDropInner, + text: str, +} + struct NoisyDropInner; impl Drop for NoisyDrop { @@ -170,7 +175,9 @@ fn main() { assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8); assert!(!intrinsics::needs_drop::()); + assert!(!intrinsics::needs_drop::<[u8]>()); assert!(intrinsics::needs_drop::()); + assert!(intrinsics::needs_drop::()); Unique { pointer: NonNull(1 as *mut &str), diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index a8435287d9fde..ddcbb0d9fc7e8 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -514,7 +514,7 @@ pub mod intrinsics { pub fn copy(src: *const T, dst: *mut T, count: usize); pub fn transmute(e: T) -> U; pub fn ctlz_nonzero(x: T) -> T; - pub fn needs_drop() -> bool; + pub fn needs_drop() -> bool; pub fn bitreverse(x: T) -> T; pub fn bswap(x: T) -> T; pub fn write_bytes(dst: *mut T, val: u8, count: usize); diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs index 69d591565acfa..14fd9eeffa6ac 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs @@ -47,6 +47,11 @@ struct NoisyDrop { inner: NoisyDropInner, } +struct NoisyDropUnsized { + inner: NoisyDropInner, + text: str, +} + struct NoisyDropInner; impl Drop for NoisyDrop { @@ -184,7 +189,9 @@ fn main() { assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8); assert!(!intrinsics::needs_drop::()); + assert!(!intrinsics::needs_drop::<[u8]>()); assert!(intrinsics::needs_drop::()); + assert!(intrinsics::needs_drop::()); Unique { pointer: 0 as *const &str, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 1d50ce767afb1..bf685aa8cadc3 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1775,30 +1775,34 @@ impl<'a> Parser<'a> { span, "macros that expand to items must be delimited with braces or followed by a semicolon", ); - if self.unclosed_delims.is_empty() { - let DelimSpan { open, close } = match args { - MacArgs::Empty | MacArgs::Eq(..) => unreachable!(), - MacArgs::Delimited(dspan, ..) => *dspan, - }; - err.multipart_suggestion( - "change the delimiters to curly braces", - vec![(open, "{".to_string()), (close, '}'.to_string())], - Applicability::MaybeIncorrect, - ); - } else { + // FIXME: This will make us not emit the help even for declarative + // macros within the same crate (that we can fix), which is sad. + if !span.from_expansion() { + if self.unclosed_delims.is_empty() { + let DelimSpan { open, close } = match args { + MacArgs::Empty | MacArgs::Eq(..) => unreachable!(), + MacArgs::Delimited(dspan, ..) => *dspan, + }; + err.multipart_suggestion( + "change the delimiters to curly braces", + vec![(open, "{".to_string()), (close, '}'.to_string())], + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion( + span, + "change the delimiters to curly braces", + " { /* items */ }", + Applicability::HasPlaceholders, + ); + } err.span_suggestion( - span, - "change the delimiters to curly braces", - " { /* items */ }", - Applicability::HasPlaceholders, + span.shrink_to_hi(), + "add a semicolon", + ';', + Applicability::MaybeIncorrect, ); } - err.span_suggestion( - span.shrink_to_hi(), - "add a semicolon", - ';', - Applicability::MaybeIncorrect, - ); err.emit(); } diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 43ba2dc287490..ba837ea9a7898 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1162,7 +1162,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop). #[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")] - pub fn needs_drop() -> bool; + pub fn needs_drop() -> bool; /// Calculates the offset from a pointer. /// diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 4ce7c8c2b607b..71ea3b4ba85a2 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -592,7 +592,7 @@ pub const unsafe fn align_of_val_raw(val: *const T) -> usize { #[stable(feature = "needs_drop", since = "1.21.0")] #[rustc_const_stable(feature = "const_mem_needs_drop", since = "1.36.0")] #[rustc_diagnostic_item = "needs_drop"] -pub const fn needs_drop() -> bool { +pub const fn needs_drop() -> bool { intrinsics::needs_drop::() } diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 4f4b06fc47de6..7157b5af00cf4 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -2257,7 +2257,7 @@ mod await_keyword {} /// `dyn` is a prefix of a [trait object]'s type. /// /// The `dyn` keyword is used to highlight that calls to methods on the associated `Trait` -/// are dynamically dispatched. To use the trait this way, it must be 'object safe'. +/// are [dynamically dispatched]. To use the trait this way, it must be 'object safe'. /// /// Unlike generic parameters or `impl Trait`, the compiler does not know the concrete type that /// is being passed. That is, the type has been [erased]. @@ -2281,6 +2281,7 @@ mod await_keyword {} /// the method won't be duplicated for each concrete type. /// /// [trait object]: ../book/ch17-02-trait-objects.html +/// [dynamically dispatched]: https://en.wikipedia.org/wiki/Dynamic_dispatch /// [ref-trait-obj]: ../reference/types/trait-object.html /// [ref-obj-safety]: ../reference/items/traits.html#object-safety /// [erased]: https://en.wikipedia.org/wiki/Type_erasure diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 5b8309cf5d273..ec68b52918802 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -316,3 +316,16 @@ fn test_scoped_threads_drop_result_before_join() { }); assert!(actually_finished.load(Ordering::Relaxed)); } + +#[test] +fn test_scoped_threads_nll() { + // this is mostly a *compilation test* for this exact function: + fn foo(x: &u8) { + thread::scope(|s| { + s.spawn(|| drop(x)); + }); + } + // let's also run it for good measure + let x = 42_u8; + foo(&x); +} diff --git a/src/test/rustdoc-json/output_generics.rs b/src/test/rustdoc-json/output_generics.rs new file mode 100644 index 0000000000000..d80656c7fc8aa --- /dev/null +++ b/src/test/rustdoc-json/output_generics.rs @@ -0,0 +1,38 @@ +// compile-flags: --document-private-items --document-hidden-items + +// This is a regression test for #98009. + +// @has output_generics.json +// @has - "$.index[*][?(@.name=='this_compiles')]" +// @has - "$.index[*][?(@.name=='this_does_not')]" +// @has - "$.index[*][?(@.name=='Events')]" +// @has - "$.index[*][?(@.name=='Other')]" +// @has - "$.index[*][?(@.name=='Trait')]" + +struct Events(R); + +struct Other; + +pub trait Trait { + fn handle(value: T) -> Self; +} + +impl Trait for T where T: From { + fn handle(_: U) -> Self { unimplemented!() } +} + +impl<'a, R> Trait<&'a mut Events> for Other { + fn handle(_: &'a mut Events) -> Self { unimplemented!() } +} + +fn this_compiles<'a, R>(value: &'a mut Events) { + for _ in 0..3 { + Other::handle(&mut *value); + } +} + +fn this_does_not<'a, R>(value: &'a mut Events) { + for _ in 0..3 { + Other::handle(value); + } +} diff --git a/src/test/ui/proc-macro/auxiliary/issue-91800-macro.rs b/src/test/ui/proc-macro/auxiliary/issue-91800-macro.rs new file mode 100644 index 0000000000000..958a8bed9e2d1 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/issue-91800-macro.rs @@ -0,0 +1,26 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +fn compile_error() -> TokenStream { + r#"compile_error!("")"#.parse().unwrap() +} + +#[proc_macro_derive(MyTrait)] +pub fn derive(input: TokenStream) -> TokenStream { + compile_error() +} +#[proc_macro_attribute] +pub fn attribute_macro(_attr: TokenStream, mut input: TokenStream) -> TokenStream { + input.extend(compile_error()); + input +} +#[proc_macro] +pub fn fn_macro(_item: TokenStream) -> TokenStream { + compile_error() +} diff --git a/src/test/ui/proc-macro/issue-91800.rs b/src/test/ui/proc-macro/issue-91800.rs new file mode 100644 index 0000000000000..0c1281de4f8c2 --- /dev/null +++ b/src/test/ui/proc-macro/issue-91800.rs @@ -0,0 +1,16 @@ +// aux-build: issue-91800-macro.rs + +#[macro_use] +extern crate issue_91800_macro; + +#[derive(MyTrait)] +//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon +//~| ERROR proc-macro derive produced unparseable tokens +#[attribute_macro] +//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon +struct MyStruct; + +fn_macro! {} +//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon + +fn main() {} diff --git a/src/test/ui/proc-macro/issue-91800.stderr b/src/test/ui/proc-macro/issue-91800.stderr new file mode 100644 index 0000000000000..9c356263a36b2 --- /dev/null +++ b/src/test/ui/proc-macro/issue-91800.stderr @@ -0,0 +1,56 @@ +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/issue-91800.rs:6:10 + | +LL | #[derive(MyTrait)] + | ^^^^^^^ + | + = note: this error originates in the derive macro `MyTrait` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: proc-macro derive produced unparseable tokens + --> $DIR/issue-91800.rs:6:10 + | +LL | #[derive(MyTrait)] + | ^^^^^^^ + +error: + --> $DIR/issue-91800.rs:6:10 + | +LL | #[derive(MyTrait)] + | ^^^^^^^ + | + = note: this error originates in the derive macro `MyTrait` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/issue-91800.rs:9:1 + | +LL | #[attribute_macro] + | ^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: + --> $DIR/issue-91800.rs:9:1 + | +LL | #[attribute_macro] + | ^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/issue-91800.rs:13:1 + | +LL | fn_macro! {} + | ^^^^^^^^^^^^ + | + = note: this error originates in the macro `fn_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: + --> $DIR/issue-91800.rs:13:1 + | +LL | fn_macro! {} + | ^^^^^^^^^^^^ + | + = note: this error originates in the macro `fn_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 7 previous errors +