diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/doc/rustc-dev-guide/src/implementing_new_features.md | 4 | ||||
| -rw-r--r-- | src/doc/rustdoc/src/unstable-features.md | 24 | ||||
| -rw-r--r-- | src/doc/unstable-book/src/language-features/unsized-locals.md | 175 | ||||
| -rw-r--r-- | src/librustdoc/doctest.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/doctest/extracted.rs | 55 | ||||
| -rw-r--r-- | src/librustdoc/doctest/make.rs | 148 | ||||
| -rw-r--r-- | src/librustdoc/doctest/tests.rs | 59 | ||||
| -rw-r--r-- | src/librustdoc/html/markdown.rs | 3 | ||||
| -rw-r--r-- | src/tools/clippy/tests/ui/large_stack_frames.rs | 8 | ||||
| -rw-r--r-- | src/tools/clippy/tests/ui/large_stack_frames.stderr | 8 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/unsized-local.rs | 23 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/unsized-local.stderr | 14 | ||||
| -rw-r--r-- | src/tools/tidy/src/issues.txt | 1 |
13 files changed, 245 insertions, 281 deletions
diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md index d7561bbbad2..5d0e875cbc1 100644 --- a/src/doc/rustc-dev-guide/src/implementing_new_features.md +++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md @@ -156,8 +156,8 @@ a new unstable feature: [`incomplete_features` lint]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#incomplete-features ```rust ignore - /// Allows unsized rvalues at arguments and parameters. - (incomplete, unsized_locals, "CURRENT_RUSTC_VERSION", Some(48055), None), + /// Allows deref patterns. + (incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), None), ``` To avoid [semantic merge conflicts], please use `CURRENT_RUSTC_VERSION` instead of `1.70` or diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 69e5a5adbec..27910ad0ab7 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -581,7 +581,9 @@ For this rust code: ```rust /// ``` +/// #![allow(dead_code)] /// let x = 12; +/// Ok(()) /// ``` pub trait Trait {} ``` @@ -590,10 +592,10 @@ The generated output (formatted) will look like this: ```json { - "format_version": 1, + "format_version": 2, "doctests": [ { - "file": "foo.rs", + "file": "src/lib.rs", "line": 1, "doctest_attributes": { "original": "", @@ -609,9 +611,17 @@ The generated output (formatted) will look like this: "added_css_classes": [], "unknown": [] }, - "original_code": "let x = 12;", - "doctest_code": "#![allow(unused)]\nfn main() {\nlet x = 12;\n}", - "name": "foo.rs - Trait (line 1)" + "original_code": "#![allow(dead_code)]\nlet x = 12;\nOk(())", + "doctest_code": { + "crate_level": "#![allow(unused)]\n#![allow(dead_code)]\n\n", + "code": "let x = 12;\nOk(())", + "wrapper": { + "before": "fn main() { fn _inner() -> core::result::Result<(), impl core::fmt::Debug> {\n", + "after": "\n} _inner().unwrap() }", + "returns_result": true + } + }, + "name": "src/lib.rs - (line 1)" } ] } @@ -624,6 +634,10 @@ The generated output (formatted) will look like this: * `doctest_attributes` contains computed information about the attributes used on the doctests. For more information about doctest attributes, take a look [here](write-documentation/documentation-tests.html#attributes). * `original_code` is the code as written in the source code before rustdoc modifies it. * `doctest_code` is the code modified by rustdoc that will be run. If there is a fatal syntax error, this field will not be present. + * `crate_level` is the crate level code (like attributes or `extern crate`) that will be added at the top-level of the generated doctest. + * `code` is "naked" doctest without anything from `crate_level` and `wrapper` content. + * `wrapper` contains extra code that will be added before and after `code`. + * `returns_result` is a boolean. If `true`, it means that the doctest returns a `Result` type. * `name` is the name generated by rustdoc which represents this doctest. ### html diff --git a/src/doc/unstable-book/src/language-features/unsized-locals.md b/src/doc/unstable-book/src/language-features/unsized-locals.md deleted file mode 100644 index d5b01a3d616..00000000000 --- a/src/doc/unstable-book/src/language-features/unsized-locals.md +++ /dev/null @@ -1,175 +0,0 @@ -# `unsized_locals` - -The tracking issue for this feature is: [#48055] - -[#48055]: https://github.com/rust-lang/rust/issues/48055 - ------------------------- - -This implements [RFC1909]. When turned on, you can have unsized arguments and locals: - -[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md - -```rust -#![allow(incomplete_features)] -#![feature(unsized_locals, unsized_fn_params)] - -use std::any::Any; - -fn main() { - let x: Box<dyn Any> = Box::new(42); - let x: dyn Any = *x; - // ^ unsized local variable - // ^^ unsized temporary - foo(x); -} - -fn foo(_: dyn Any) {} -// ^^^^^^ unsized argument -``` - -The RFC still forbids the following unsized expressions: - -```rust,compile_fail -#![feature(unsized_locals)] - -use std::any::Any; - -struct MyStruct<T: ?Sized> { - content: T, -} - -struct MyTupleStruct<T: ?Sized>(T); - -fn answer() -> Box<dyn Any> { - Box::new(42) -} - -fn main() { - // You CANNOT have unsized statics. - static X: dyn Any = *answer(); // ERROR - const Y: dyn Any = *answer(); // ERROR - - // You CANNOT have struct initialized unsized. - MyStruct { content: *answer() }; // ERROR - MyTupleStruct(*answer()); // ERROR - (42, *answer()); // ERROR - - // You CANNOT have unsized return types. - fn my_function() -> dyn Any { *answer() } // ERROR - - // You CAN have unsized local variables... - let mut x: dyn Any = *answer(); // OK - // ...but you CANNOT reassign to them. - x = *answer(); // ERROR - - // You CANNOT even initialize them separately. - let y: dyn Any; // OK - y = *answer(); // ERROR - - // Not mentioned in the RFC, but by-move captured variables are also Sized. - let x: dyn Any = *answer(); - (move || { // ERROR - let y = x; - })(); - - // You CAN create a closure with unsized arguments, - // but you CANNOT call it. - // This is an implementation detail and may be changed in the future. - let f = |x: dyn Any| {}; - f(*answer()); // ERROR -} -``` - -## By-value trait objects - -With this feature, you can have by-value `self` arguments without `Self: Sized` bounds. - -```rust -#![feature(unsized_fn_params)] - -trait Foo { - fn foo(self) {} -} - -impl<T: ?Sized> Foo for T {} - -fn main() { - let slice: Box<[i32]> = Box::new([1, 2, 3]); - <[i32] as Foo>::foo(*slice); -} -``` - -And `Foo` will also be object-safe. - -```rust -#![feature(unsized_fn_params)] - -trait Foo { - fn foo(self) {} -} - -impl<T: ?Sized> Foo for T {} - -fn main () { - let slice: Box<dyn Foo> = Box::new([1, 2, 3]); - // doesn't compile yet - <dyn Foo as Foo>::foo(*slice); -} -``` - -One of the objectives of this feature is to allow `Box<dyn FnOnce>`. - -## Variable length arrays - -The RFC also describes an extension to the array literal syntax: `[e; dyn n]`. In the syntax, `n` isn't necessarily a constant expression. The array is dynamically allocated on the stack and has the type of `[T]`, instead of `[T; n]`. - -```rust,ignore (not-yet-implemented) -#![feature(unsized_locals)] - -fn mergesort<T: Ord>(a: &mut [T]) { - let mut tmp = [T; dyn a.len()]; - // ... -} - -fn main() { - let mut a = [3, 1, 5, 6]; - mergesort(&mut a); - assert_eq!(a, [1, 3, 5, 6]); -} -``` - -VLAs are not implemented yet. The syntax isn't final, either. We may need an alternative syntax for Rust 2015 because, in Rust 2015, expressions like `[e; dyn(1)]` would be ambiguous. One possible alternative proposed in the RFC is `[e; n]`: if `n` captures one or more local variables, then it is considered as `[e; dyn n]`. - -## Advisory on stack usage - -It's advised not to casually use the `#![feature(unsized_locals)]` feature. Typical use-cases are: - -- When you need a by-value trait objects. -- When you really need a fast allocation of small temporary arrays. - -Another pitfall is repetitive allocation and temporaries. Currently the compiler simply extends the stack frame every time it encounters an unsized assignment. So for example, the code - -```rust -#![feature(unsized_locals)] - -fn main() { - let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]); - let _x = {{{{{{{{{{*x}}}}}}}}}}; -} -``` - -and the code - -```rust -#![feature(unsized_locals)] - -fn main() { - for _ in 0..10 { - let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]); - let _x = *x; - } -} -``` - -will unnecessarily extend the stack frame. diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a81d6020f71..130fdff1afe 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1053,14 +1053,14 @@ fn doctest_run_fn( let report_unused_externs = |uext| { unused_externs.lock().unwrap().push(uext); }; - let (full_test_code, full_test_line_offset) = doctest.generate_unique_doctest( + let (wrapped, full_test_line_offset) = doctest.generate_unique_doctest( &scraped_test.text, scraped_test.langstr.test_harness, &global_opts, Some(&global_opts.crate_name), ); let runnable_test = RunnableDocTest { - full_test_code, + full_test_code: wrapped.to_string(), full_test_line_offset, test_opts, global_opts, diff --git a/src/librustdoc/doctest/extracted.rs b/src/librustdoc/doctest/extracted.rs index ebe6bfd22ba..925fb6fee2c 100644 --- a/src/librustdoc/doctest/extracted.rs +++ b/src/librustdoc/doctest/extracted.rs @@ -3,8 +3,10 @@ //! This module contains the logic to extract doctests and output a JSON containing this //! information. +use rustc_span::edition::Edition; use serde::Serialize; +use super::make::DocTestWrapResult; use super::{BuildDocTestBuilder, ScrapedDocTest}; use crate::config::Options as RustdocOptions; use crate::html::markdown; @@ -14,7 +16,7 @@ use crate::html::markdown; /// This integer is incremented with every breaking change to the API, /// and is returned along with the JSON blob into the `format_version` root field. /// Consuming code should assert that this value matches the format version(s) that it supports. -const FORMAT_VERSION: u32 = 1; +const FORMAT_VERSION: u32 = 2; #[derive(Serialize)] pub(crate) struct ExtractedDocTests { @@ -34,7 +36,16 @@ impl ExtractedDocTests { options: &RustdocOptions, ) { let edition = scraped_test.edition(options); + self.add_test_with_edition(scraped_test, opts, edition) + } + /// This method is used by unit tests to not have to provide a `RustdocOptions`. + pub(crate) fn add_test_with_edition( + &mut self, + scraped_test: ScrapedDocTest, + opts: &super::GlobalTestOptions, + edition: Edition, + ) { let ScrapedDocTest { filename, line, langstr, text, name, global_crate_attrs, .. } = scraped_test; @@ -44,8 +55,7 @@ impl ExtractedDocTests { .edition(edition) .lang_str(&langstr) .build(None); - - let (full_test_code, size) = doctest.generate_unique_doctest( + let (wrapped, _size) = doctest.generate_unique_doctest( &text, langstr.test_harness, opts, @@ -55,11 +65,46 @@ impl ExtractedDocTests { file: filename.prefer_remapped_unconditionaly().to_string(), line, doctest_attributes: langstr.into(), - doctest_code: if size != 0 { Some(full_test_code) } else { None }, + doctest_code: match wrapped { + DocTestWrapResult::Valid { crate_level_code, wrapper, code } => Some(DocTest { + crate_level: crate_level_code, + code, + wrapper: wrapper.map( + |super::make::WrapperInfo { before, after, returns_result, .. }| { + WrapperInfo { before, after, returns_result } + }, + ), + }), + DocTestWrapResult::SyntaxError { .. } => None, + }, original_code: text, name, }); } + + #[cfg(test)] + pub(crate) fn doctests(&self) -> &[ExtractedDocTest] { + &self.doctests + } +} + +#[derive(Serialize)] +pub(crate) struct WrapperInfo { + before: String, + after: String, + returns_result: bool, +} + +#[derive(Serialize)] +pub(crate) struct DocTest { + crate_level: String, + code: String, + /// This field can be `None` if one of the following conditions is true: + /// + /// * The doctest's codeblock has the `test_harness` attribute. + /// * The doctest has a `main` function. + /// * The doctest has the `![no_std]` attribute. + pub(crate) wrapper: Option<WrapperInfo>, } #[derive(Serialize)] @@ -69,7 +114,7 @@ pub(crate) struct ExtractedDocTest { doctest_attributes: LangString, original_code: String, /// `None` if the code syntax is invalid. - doctest_code: Option<String>, + pub(crate) doctest_code: Option<DocTest>, name: String, } diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 5e571613d6f..3ff6828e52f 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -196,6 +196,80 @@ pub(crate) struct DocTestBuilder { pub(crate) can_be_merged: bool, } +/// Contains needed information for doctest to be correctly generated with expected "wrapping". +pub(crate) struct WrapperInfo { + pub(crate) before: String, + pub(crate) after: String, + pub(crate) returns_result: bool, + insert_indent_space: bool, +} + +impl WrapperInfo { + fn len(&self) -> usize { + self.before.len() + self.after.len() + } +} + +/// Contains a doctest information. Can be converted into code with the `to_string()` method. +pub(crate) enum DocTestWrapResult { + Valid { + crate_level_code: String, + /// This field can be `None` if one of the following conditions is true: + /// + /// * The doctest's codeblock has the `test_harness` attribute. + /// * The doctest has a `main` function. + /// * The doctest has the `![no_std]` attribute. + wrapper: Option<WrapperInfo>, + /// Contains the doctest processed code without the wrappers (which are stored in the + /// `wrapper` field). + code: String, + }, + /// Contains the original source code. + SyntaxError(String), +} + +impl std::string::ToString for DocTestWrapResult { + fn to_string(&self) -> String { + match self { + Self::SyntaxError(s) => s.clone(), + Self::Valid { crate_level_code, wrapper, code } => { + let mut prog_len = code.len() + crate_level_code.len(); + if let Some(wrapper) = wrapper { + prog_len += wrapper.len(); + if wrapper.insert_indent_space { + prog_len += code.lines().count() * 4; + } + } + let mut prog = String::with_capacity(prog_len); + + prog.push_str(crate_level_code); + if let Some(wrapper) = wrapper { + prog.push_str(&wrapper.before); + + // add extra 4 spaces for each line to offset the code block + if wrapper.insert_indent_space { + write!( + prog, + "{}", + fmt::from_fn(|f| code + .lines() + .map(|line| fmt::from_fn(move |f| write!(f, " {line}"))) + .joined("\n", f)) + ) + .unwrap(); + } else { + prog.push_str(code); + } + prog.push_str(&wrapper.after); + } else { + prog.push_str(code); + } + prog + } + } + } +} + impl DocTestBuilder { fn invalid( global_crate_attrs: Vec<String>, @@ -228,50 +302,49 @@ impl DocTestBuilder { dont_insert_main: bool, opts: &GlobalTestOptions, crate_name: Option<&str>, - ) -> (String, usize) { + ) -> (DocTestWrapResult, usize) { if self.invalid_ast { // If the AST failed to compile, no need to go generate a complete doctest, the error // will be better this way. debug!("invalid AST:\n{test_code}"); - return (test_code.to_string(), 0); + return (DocTestWrapResult::SyntaxError(test_code.to_string()), 0); } let mut line_offset = 0; - let mut prog = String::new(); - let everything_else = self.everything_else.trim(); - + let mut crate_level_code = String::new(); + let processed_code = self.everything_else.trim(); if self.global_crate_attrs.is_empty() { // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some // lints that are commonly triggered in doctests. The crate-level test attributes are // commonly used to make tests fail in case they trigger warnings, so having this there in // that case may cause some tests to pass when they shouldn't have. - prog.push_str("#![allow(unused)]\n"); + crate_level_code.push_str("#![allow(unused)]\n"); line_offset += 1; } // Next, any attributes that came from #![doc(test(attr(...)))]. for attr in &self.global_crate_attrs { - prog.push_str(&format!("#![{attr}]\n")); + crate_level_code.push_str(&format!("#![{attr}]\n")); line_offset += 1; } // Now push any outer attributes from the example, assuming they // are intended to be crate attributes. if !self.crate_attrs.is_empty() { - prog.push_str(&self.crate_attrs); + crate_level_code.push_str(&self.crate_attrs); if !self.crate_attrs.ends_with('\n') { - prog.push('\n'); + crate_level_code.push('\n'); } } if !self.maybe_crate_attrs.is_empty() { - prog.push_str(&self.maybe_crate_attrs); + crate_level_code.push_str(&self.maybe_crate_attrs); if !self.maybe_crate_attrs.ends_with('\n') { - prog.push('\n'); + crate_level_code.push('\n'); } } if !self.crates.is_empty() { - prog.push_str(&self.crates); + crate_level_code.push_str(&self.crates); if !self.crates.ends_with('\n') { - prog.push('\n'); + crate_level_code.push('\n'); } } @@ -289,17 +362,20 @@ impl DocTestBuilder { { // rustdoc implicitly inserts an `extern crate` item for the own crate // which may be unused, so we need to allow the lint. - prog.push_str("#[allow(unused_extern_crates)]\n"); + crate_level_code.push_str("#[allow(unused_extern_crates)]\n"); - prog.push_str(&format!("extern crate r#{crate_name};\n")); + crate_level_code.push_str(&format!("extern crate r#{crate_name};\n")); line_offset += 1; } // FIXME: This code cannot yet handle no_std test cases yet - if dont_insert_main || self.has_main_fn || prog.contains("![no_std]") { - prog.push_str(everything_else); + let wrapper = if dont_insert_main + || self.has_main_fn + || crate_level_code.contains("![no_std]") + { + None } else { - let returns_result = everything_else.ends_with("(())"); + let returns_result = processed_code.ends_with("(())"); // Give each doctest main function a unique name. // This is for example needed for the tooling around `-C instrument-coverage`. let inner_fn_name = if let Some(ref test_id) = self.test_id { @@ -333,28 +409,22 @@ impl DocTestBuilder { // /// ``` <- end of the inner main line_offset += 1; - prog.push_str(&main_pre); - - // add extra 4 spaces for each line to offset the code block - if opts.insert_indent_space { - write!( - prog, - "{}", - fmt::from_fn(|f| everything_else - .lines() - .map(|line| fmt::from_fn(move |f| write!(f, " {line}"))) - .joined("\n", f)) - ) - .unwrap(); - } else { - prog.push_str(everything_else); - }; - prog.push_str(&main_post); - } - - debug!("final doctest:\n{prog}"); + Some(WrapperInfo { + before: main_pre, + after: main_post, + returns_result, + insert_indent_space: opts.insert_indent_space, + }) + }; - (prog, line_offset) + ( + DocTestWrapResult::Valid { + code: processed_code.to_string(), + wrapper, + crate_level_code, + }, + line_offset, + ) } } diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index ce2984ced79..ccc3e55a331 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -1,6 +1,11 @@ use std::path::PathBuf; -use super::{BuildDocTestBuilder, GlobalTestOptions}; +use rustc_span::edition::Edition; +use rustc_span::{DUMMY_SP, FileName}; + +use super::extracted::ExtractedDocTests; +use super::{BuildDocTestBuilder, GlobalTestOptions, ScrapedDocTest}; +use crate::html::markdown::LangString; fn make_test( test_code: &str, @@ -19,9 +24,9 @@ fn make_test( builder = builder.test_id(test_id.to_string()); } let doctest = builder.build(None); - let (code, line_offset) = + let (wrapped, line_offset) = doctest.generate_unique_doctest(test_code, dont_insert_main, opts, crate_name); - (code, line_offset) + (wrapped.to_string(), line_offset) } /// Default [`GlobalTestOptions`] for these unit tests. @@ -461,3 +466,51 @@ pub mod outer_module { let (output, len) = make_test(input, None, false, &opts, Vec::new(), None); assert_eq!((output, len), (expected, 2)); } + +fn get_extracted_doctests(code: &str) -> ExtractedDocTests { + let opts = default_global_opts(""); + let mut extractor = ExtractedDocTests::new(); + extractor.add_test_with_edition( + ScrapedDocTest::new( + FileName::Custom(String::new()), + 0, + Vec::new(), + LangString::default(), + code.to_string(), + DUMMY_SP, + Vec::new(), + ), + &opts, + Edition::Edition2018, + ); + extractor +} + +// Test that `extracted::DocTest::wrapper` is `None` if the doctest has a `main` function. +#[test] +fn test_extracted_doctest_wrapper_field() { + let extractor = get_extracted_doctests("fn main() {}"); + + assert_eq!(extractor.doctests().len(), 1); + let doctest_code = extractor.doctests()[0].doctest_code.as_ref().unwrap(); + assert!(doctest_code.wrapper.is_none()); +} + +// Test that `ExtractedDocTest::doctest_code` is `None` if the doctest has syntax error. +#[test] +fn test_extracted_doctest_doctest_code_field() { + let extractor = get_extracted_doctests("let x +="); + + assert_eq!(extractor.doctests().len(), 1); + assert!(extractor.doctests()[0].doctest_code.is_none()); +} + +// Test that `extracted::DocTest::wrapper` is `Some` if the doctest needs wrapping. +#[test] +fn test_extracted_doctest_wrapper_field_with_info() { + let extractor = get_extracted_doctests("let x = 12;"); + + assert_eq!(extractor.doctests().len(), 1); + let doctest_code = extractor.doctests()[0].doctest_code.as_ref().unwrap(); + assert!(doctest_code.wrapper.is_some()); +} diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index d3701784f9d..f626e07b000 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -307,7 +307,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> { builder = builder.crate_name(krate); } let doctest = builder.build(None); - let (test, _) = doctest.generate_unique_doctest(&test, false, &opts, krate); + let (wrapped, _) = doctest.generate_unique_doctest(&test, false, &opts, krate); + let test = wrapped.to_string(); let channel = if test.contains("#![feature(") { "&version=nightly" } else { "" }; let test_escaped = small_url_encode(test); diff --git a/src/tools/clippy/tests/ui/large_stack_frames.rs b/src/tools/clippy/tests/ui/large_stack_frames.rs index 3ed124f69ef..132f1450b6d 100644 --- a/src/tools/clippy/tests/ui/large_stack_frames.rs +++ b/src/tools/clippy/tests/ui/large_stack_frames.rs @@ -1,8 +1,7 @@ //@ normalize-stderr-test: "\b10000(08|16|32)\b" -> "100$$PTR" //@ normalize-stderr-test: "\b2500(060|120)\b" -> "250$$PTR" -#![allow(unused, incomplete_features)] +#![allow(unused)] #![warn(clippy::large_stack_frames)] -#![feature(unsized_locals)] use std::hint::black_box; @@ -11,11 +10,6 @@ fn generic<T: Default>() { black_box(&x); } -fn unsized_local() { - let x: dyn std::fmt::Display = *(Box::new(1) as Box<dyn std::fmt::Display>); - black_box(&x); -} - struct ArrayDefault<const N: usize>([u8; N]); impl<const N: usize> Default for ArrayDefault<N> { diff --git a/src/tools/clippy/tests/ui/large_stack_frames.stderr b/src/tools/clippy/tests/ui/large_stack_frames.stderr index 0ff49e9f5b3..79482e65c3e 100644 --- a/src/tools/clippy/tests/ui/large_stack_frames.stderr +++ b/src/tools/clippy/tests/ui/large_stack_frames.stderr @@ -1,5 +1,5 @@ error: this function may allocate 250$PTR bytes on the stack - --> tests/ui/large_stack_frames.rs:27:4 + --> tests/ui/large_stack_frames.rs:21:4 | LL | fn many_small_arrays() { | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | let x5 = [0u8; 500_000]; = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]` error: this function may allocate 1000000 bytes on the stack - --> tests/ui/large_stack_frames.rs:38:4 + --> tests/ui/large_stack_frames.rs:32:4 | LL | fn large_return_value() -> ArrayDefault<1_000_000> { | ^^^^^^^^^^^^^^^^^^ ----------------------- this is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>` @@ -21,7 +21,7 @@ LL | fn large_return_value() -> ArrayDefault<1_000_000> { = note: 1000000 bytes is larger than Clippy's configured `stack-size-threshold` of 512000 error: this function may allocate 100$PTR bytes on the stack - --> tests/ui/large_stack_frames.rs:44:4 + --> tests/ui/large_stack_frames.rs:38:4 | LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) { | ^^^^^^^^^^^^ - `x` is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>` @@ -29,7 +29,7 @@ LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) { = note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000 error: this function may allocate 100$PTR bytes on the stack - --> tests/ui/large_stack_frames.rs:51:13 + --> tests/ui/large_stack_frames.rs:45:13 | LL | let f = || black_box(&[0u8; 1_000_000]); | ^^^^^^^^^^^^^^----------------^ diff --git a/src/tools/miri/tests/fail/unsized-local.rs b/src/tools/miri/tests/fail/unsized-local.rs deleted file mode 100644 index ceccae4e3e7..00000000000 --- a/src/tools/miri/tests/fail/unsized-local.rs +++ /dev/null @@ -1,23 +0,0 @@ -#![feature(unsized_locals)] -#![allow(incomplete_features)] - -fn main() { - pub trait Foo { - fn foo(self) -> String; - } - - struct A; - - impl Foo for A { - fn foo(self) -> String { - format!("hello") - } - } - - let x = *(Box::new(A) as Box<dyn Foo>); //~ERROR: unsized locals are not supported - assert_eq!(x.foo(), format!("hello")); - - // I'm not sure whether we want this to work - let x = Box::new(A) as Box<dyn Foo>; - assert_eq!(x.foo(), format!("hello")); -} diff --git a/src/tools/miri/tests/fail/unsized-local.stderr b/src/tools/miri/tests/fail/unsized-local.stderr deleted file mode 100644 index 548f3d66c73..00000000000 --- a/src/tools/miri/tests/fail/unsized-local.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: unsupported operation: unsized locals are not supported - --> tests/fail/unsized-local.rs:LL:CC - | -LL | let x = *(Box::new(A) as Box<dyn Foo>); - | ^ unsized locals are not supported - | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at tests/fail/unsized-local.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 3e9d79224fd..045f2f0692a 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -754,7 +754,6 @@ ui/consts/issue-46553.rs ui/consts/issue-47789.rs ui/consts/issue-50439.rs ui/consts/issue-52023-array-size-pointer-cast.rs -ui/consts/issue-54224.rs ui/consts/issue-54348.rs ui/consts/issue-54387.rs ui/consts/issue-54582.rs |
