From a072ecbf70eef05f2904031169e493782d65dd37 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 20 Jan 2021 17:14:15 +0000 Subject: [PATCH 01/26] Don't build remote-test-server with the stage0 toolchain Newly added targets aren't available on the stage0 toolchain. --- src/bootstrap/test.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 335a173100290..ef2790e3f3809 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1932,8 +1932,7 @@ impl Step for RemoteCopyLibs { builder.info(&format!("REMOTE copy libs to emulator ({})", target)); t!(fs::create_dir_all(builder.out.join("tmp"))); - let server = - builder.ensure(tool::RemoteTestServer { compiler: compiler.with_stage(0), target }); + let server = builder.ensure(tool::RemoteTestServer { compiler, target }); // Spawn the emulator and wait for it to come online let tool = builder.tool_exe(Tool::RemoteTestClient); From b5482a8f166b952f397be0432dec062b5b0ca105 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 20 Jan 2021 18:37:14 +0000 Subject: [PATCH 02/26] Preserve existing LD_LIBRARY_PATH in remote-test-server --- src/tools/remote-test-server/src/main.rs | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index d92758eb7474c..cd9d530096496 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -218,25 +218,19 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf cmd.args(args); cmd.envs(env); + // On windows, libraries are just searched in the executable directory, + // system directories, PWD, and PATH, in that order. PATH is the only one + // we can change for this. + let library_path = if cfg!(windows) { "PATH" } else { "LD_LIBRARY_PATH" }; + // Support libraries were uploaded to `work` earlier, so make sure that's // in `LD_LIBRARY_PATH`. Also include our own current dir which may have // had some libs uploaded. - if cfg!(windows) { - // On windows, libraries are just searched in the executable directory, - // system directories, PWD, and PATH, in that order. PATH is the only one - // we can change for this. - cmd.env( - "PATH", - env::join_paths( - std::iter::once(work.to_owned()) - .chain(std::iter::once(path.clone())) - .chain(env::split_paths(&env::var_os("PATH").unwrap())), - ) - .unwrap(), - ); - } else { - cmd.env("LD_LIBRARY_PATH", format!("{}:{}", work.display(), path.display())); + let mut paths = vec![work.to_owned(), path.clone()]; + if let Some(library_path) = env::var_os(library_path) { + paths.extend(env::split_paths(&library_path)); } + cmd.env(library_path, env::join_paths(paths).unwrap()); // Some tests assume RUST_TEST_TMPDIR exists cmd.env("RUST_TEST_TMPDIR", tmp.to_owned()); From a2f5c72a2d5e27a617e4d2dcca1053b0c34b36ed Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Sat, 23 Jan 2021 20:37:56 -0500 Subject: [PATCH 03/26] Fix has_body for trait methods --- src/librustdoc/json/conversions.rs | 20 +++++++++----------- src/test/rustdoc-json/traits/has_body.rs | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 src/test/rustdoc-json/traits/has_body.rs diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index b2e5c8834b8ff..438a8d57cc222 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -162,8 +162,8 @@ impl From for ItemEnum { ForeignFunctionItem(f) => ItemEnum::FunctionItem(f.into()), TraitItem(t) => ItemEnum::TraitItem(t.into()), TraitAliasItem(t) => ItemEnum::TraitAliasItem(t.into()), - MethodItem(m, _) => ItemEnum::MethodItem(m.into()), - TyMethodItem(m) => ItemEnum::MethodItem(m.into()), + MethodItem(m, _) => ItemEnum::MethodItem(from_function_method(m, true)), + TyMethodItem(m) => ItemEnum::MethodItem(from_function_method(m, false)), ImplItem(i) => ItemEnum::ImplItem(i.into()), StaticItem(s) => ItemEnum::StaticItem(s.into()), ForeignStaticItem(s) => ItemEnum::StaticItem(s.into()), @@ -435,15 +435,13 @@ impl From for Impl { } } -impl From for Method { - fn from(function: clean::Function) -> Self { - let clean::Function { header, decl, generics, all_types: _, ret_types: _ } = function; - Method { - decl: decl.into(), - generics: generics.into(), - header: stringify_header(&header), - has_body: true, - } +crate fn from_function_method(function: clean::Function, has_body: bool) -> Method { + let clean::Function { header, decl, generics, all_types: _, ret_types: _ } = function; + Method { + decl: decl.into(), + generics: generics.into(), + header: stringify_header(&header), + has_body, } } diff --git a/src/test/rustdoc-json/traits/has_body.rs b/src/test/rustdoc-json/traits/has_body.rs new file mode 100644 index 0000000000000..853be19a3879f --- /dev/null +++ b/src/test/rustdoc-json/traits/has_body.rs @@ -0,0 +1,22 @@ + +// @has has_body.json "$.index[*][?(@.name=='Foo')]" +pub trait Foo { + // @has - "$.index[*][?(@.name=='no_self')].inner.has_body" false + fn no_self(); + // @has - "$.index[*][?(@.name=='move_self')].inner.has_body" false + fn move_self(self); + // @has - "$.index[*][?(@.name=='ref_self')].inner.has_body" false + fn ref_self(&self); + + // @has - "$.index[*][?(@.name=='no_self_def')].inner.has_body" true + fn no_self_def() {} + // @has - "$.index[*][?(@.name=='move_self_def')].inner.has_body" true + fn move_self_def(self) {} + // @has - "$.index[*][?(@.name=='ref_self_def')].inner.has_body" true + fn ref_self_def(&self) {} +} + +pub trait Bar: Clone { + // @has - "$.index[*][?(@.name=='method')].inner.has_body" false + fn method(&self, param: usize); +} From 1c60d27a52ee0341c3848f170c2635d5e74bd0a8 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Sat, 23 Jan 2021 21:17:15 -0500 Subject: [PATCH 04/26] Remove leading newline --- src/test/rustdoc-json/traits/has_body.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/rustdoc-json/traits/has_body.rs b/src/test/rustdoc-json/traits/has_body.rs index 853be19a3879f..44dacb1ee75bf 100644 --- a/src/test/rustdoc-json/traits/has_body.rs +++ b/src/test/rustdoc-json/traits/has_body.rs @@ -1,4 +1,3 @@ - // @has has_body.json "$.index[*][?(@.name=='Foo')]" pub trait Foo { // @has - "$.index[*][?(@.name=='no_self')].inner.has_body" false From 3106de5f2a0983f617433d6e3429ff1a90d71f8d Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Sat, 23 Jan 2021 19:40:29 -0500 Subject: [PATCH 05/26] Remove struct_type from union output and bump format --- src/librustdoc/json/conversions.rs | 7 +++---- src/librustdoc/json/mod.rs | 2 +- src/rustdoc-json-types/lib.rs | 10 +++++++++- src/test/rustdoc-json/unions/union.rs | 7 +++++++ 4 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 src/test/rustdoc-json/unions/union.rs diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index b2e5c8834b8ff..9c4d3becbdaef 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -154,7 +154,7 @@ impl From for ItemEnum { } ImportItem(i) => ItemEnum::ImportItem(i.into()), StructItem(s) => ItemEnum::StructItem(s.into()), - UnionItem(u) => ItemEnum::StructItem(u.into()), + UnionItem(u) => ItemEnum::UnionItem(u.into()), StructFieldItem(f) => ItemEnum::StructFieldItem(f.into()), EnumItem(e) => ItemEnum::EnumItem(e.into()), VariantItem(v) => ItemEnum::VariantItem(v.into()), @@ -205,11 +205,10 @@ impl From for Struct { } } -impl From for Struct { +impl From for Union { fn from(struct_: clean::Union) -> Self { let clean::Union { generics, fields, fields_stripped } = struct_; - Struct { - struct_type: StructType::Union, + Union { generics: generics.into(), fields_stripped, fields: ids(fields), diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index a7c875fb7480b..876b1b56dee6d 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -243,7 +243,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .collect(), - format_version: 2, + format_version: 3, }; let mut p = self.out_path.clone(); p.push(output.index.get(&output.root).unwrap().name.clone().unwrap()); diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 3fb2a32d5a0a3..083f99e4a681a 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -194,6 +194,7 @@ pub enum ItemEnum { }, ImportItem(Import), + UnionItem(Union), StructItem(Struct), StructFieldItem(Type), EnumItem(Enum), @@ -238,6 +239,14 @@ pub struct Module { pub items: Vec, } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub struct Union { + pub generics: Generics, + pub fields_stripped: bool, + pub fields: Vec, + pub impls: Vec, +} + #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct Struct { pub struct_type: StructType, @@ -270,7 +279,6 @@ pub enum StructType { Plain, Tuple, Unit, - Union, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] diff --git a/src/test/rustdoc-json/unions/union.rs b/src/test/rustdoc-json/unions/union.rs new file mode 100644 index 0000000000000..ac2eb797791f3 --- /dev/null +++ b/src/test/rustdoc-json/unions/union.rs @@ -0,0 +1,7 @@ +// @has union.json "$.index[*][?(@.name=='Union')].visibility" \"public\" +// @has - "$.index[*][?(@.name=='Union')].kind" \"union\" +// @!has - "$.index[*][?(@.name=='Union')].inner.struct_type" +pub union Union { + int: i32, + float: f32, +} From c34faadfdaf3938f24e9f7a4c3441ac581078ce4 Mon Sep 17 00:00:00 2001 From: Camelid Date: Thu, 28 Jan 2021 19:04:29 -0800 Subject: [PATCH 06/26] rustdoc: Move `display_fn` struct inside `display_fn` This makes it clear that it's an implementation detail of `display_fn` and shouldn't be used elsewhere, and it enforces in the compiler that no one else can use it. --- src/librustdoc/html/format.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 01915c33a07ad..8fd1c1d1cc652 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1322,16 +1322,16 @@ impl clean::GenericArg { } crate fn display_fn(f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Display { - WithFormatter(Cell::new(Some(f))) -} - -struct WithFormatter(Cell>); - -impl fmt::Display for WithFormatter -where - F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (self.0.take()).unwrap()(f) + struct WithFormatter(Cell>); + + impl fmt::Display for WithFormatter + where + F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (self.0.take()).unwrap()(f) + } } + + WithFormatter(Cell::new(Some(f))) } From 5882cce54ea902c234421c19de0a26a2adcaf6cc Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Sat, 30 Jan 2021 02:12:40 +0000 Subject: [PATCH 07/26] Expose correct symlink API on WASI As described in https://github.com/rust-lang/rust/issues/68574, the currently exposed API for symlinks is, in fact, a thin wrapper around the corresponding syscall, and not suitable for public usage. The reason is that the 2nd param in the call is expected to be a handle of a "preopened directory" (a WASI concept for exposing dirs), and the only way to retrieve such handle right now is by tinkering with a private `__wasilibc_find_relpath` API, which is an implementation detail and definitely not something we want users to call directly. Making matters worse, the semantics of this param aren't obvious from its name (`fd`), and easy to misinterpret, resulting in people trying to pass a handle of the target file itself (as in https://github.com/vitiral/path_abs/pull/50), which doesn't work as expected. I did a codesearch among open-source repos, and the usage above is so far the only usage of this API at all, but we should fix it before more people start using it incorrectly. While this is technically a breaking API change, I believe it's a justified one, as 1) it's OS-specific and 2) there was strictly no way to correctly use the previous form of the API, and if someone does use it, they're likely doing it wrong like in the example above. The new API does not lead to the same confusion, as it mirrors `std::os::unix::fs::symlink` and `std::os::windows::fs::symlink_{file,dir}` variants by accepting source/target paths. Fixes #68574. --- library/std/src/sys/wasi/ext/fs.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs index 4f7cf6018d90f..36530e4bb35a6 100644 --- a/library/std/src/sys/wasi/ext/fs.rs +++ b/library/std/src/sys/wasi/ext/fs.rs @@ -504,13 +504,9 @@ pub fn rename, U: AsRef>( /// Create a symbolic link. /// -/// This corresponds to the `path_symlink` syscall. -pub fn symlink, U: AsRef>( - old_path: P, - fd: &File, - new_path: U, -) -> io::Result<()> { - fd.as_inner() - .fd() - .symlink(osstr2str(old_path.as_ref().as_ref())?, osstr2str(new_path.as_ref().as_ref())?) +/// This is similar to [`std::os::unix::fs::symlink`] and +/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir) +/// counterparts. +pub fn symlink, U: AsRef>(old_path: P, new_path: U) -> io::Result<()> { + crate::sys::fs::symlink(old_path.as_ref(), new_path.as_ref()) } From 6e6608d8b54319aff0f5e6a3e10bd25aa508c329 Mon Sep 17 00:00:00 2001 From: kadmin Date: Tue, 2 Feb 2021 21:44:32 +0000 Subject: [PATCH 08/26] Add additional benchmarks to bit_set --- compiler/rustc_index/src/bit_set/tests.rs | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs index 6cc3e9427d1a7..c11b98e77aa58 100644 --- a/compiler/rustc_index/src/bit_set/tests.rs +++ b/compiler/rustc_index/src/bit_set/tests.rs @@ -1,6 +1,7 @@ use super::*; extern crate test; +use std::hint::black_box; use test::Bencher; #[test] @@ -364,3 +365,36 @@ fn union_hybrid_sparse_full_small_domain(b: &mut Bencher) { sparse.union(&dense); }) } + +#[bench] +fn bench_insert(b: &mut Bencher) { + let mut bs = BitSet::new_filled(99999usize); + b.iter(|| { + black_box(bs.insert(black_box(100u32))); + }); +} + +#[bench] +fn bench_remove(b: &mut Bencher) { + let mut bs = BitSet::new_filled(99999usize); + b.iter(|| { + black_box(bs.remove(black_box(100u32))); + }); +} + +#[bench] +fn bench_iter(b: &mut Bencher) { + let bs = BitSet::new_filled(99999usize); + b.iter(|| { + bs.iter().map(|b: usize| black_box(b)).for_each(drop); + }); +} + +#[bench] +fn bench_intersect(b: &mut Bencher) { + let mut ba: BitSet = BitSet::new_filled(99999usize); + let bb = BitSet::new_filled(99999usize); + b.iter(|| { + ba.intersect(black_box(&bb)); + }); +} From 1578f2e1e8736e4e68f720146247d402bee6c1bf Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 3 Feb 2021 15:45:30 +0000 Subject: [PATCH 09/26] Keep old symlink; expose new symlink_path --- library/std/src/sys/wasi/ext/fs.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs index 36530e4bb35a6..42adcd777dc63 100644 --- a/library/std/src/sys/wasi/ext/fs.rs +++ b/library/std/src/sys/wasi/ext/fs.rs @@ -502,11 +502,21 @@ pub fn rename, U: AsRef>( ) } +/// This corresponds to the `path_symlink` syscall. +pub fn symlink, U: AsRef>( + old_path: P, + fd: &File, + new_path: U, +) -> io::Result<()> { + fd.as_inner() + .fd() + .symlink(osstr2str(old_path.as_ref().as_ref())?, osstr2str(new_path.as_ref().as_ref())?) +} + /// Create a symbolic link. /// -/// This is similar to [`std::os::unix::fs::symlink`] and -/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir) -/// counterparts. -pub fn symlink, U: AsRef>(old_path: P, new_path: U) -> io::Result<()> { +/// This is a convenience API similar to [`std::os::unix::fs::symlink`] and +/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir). +pub fn symlink_path, U: AsRef>(old_path: P, new_path: U) -> io::Result<()> { crate::sys::fs::symlink(old_path.as_ref(), new_path.as_ref()) } From f4b1bef542b209ba92187b06d19f84374e51a746 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 3 Feb 2021 15:46:57 +0000 Subject: [PATCH 10/26] Restore comment as it was --- library/std/src/sys/wasi/ext/fs.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs index 42adcd777dc63..a8da003d550ac 100644 --- a/library/std/src/sys/wasi/ext/fs.rs +++ b/library/std/src/sys/wasi/ext/fs.rs @@ -502,6 +502,8 @@ pub fn rename, U: AsRef>( ) } +/// Create a symbolic link. +/// /// This corresponds to the `path_symlink` syscall. pub fn symlink, U: AsRef>( old_path: P, From 82914a503119b35b9fd0d33384136049bc6750cc Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 2 Feb 2021 15:48:50 -0500 Subject: [PATCH 11/26] Add more information to the error code for 'crate not found' This comes up a lot when bootstrapping. --- .../src/error_codes/E0463.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/compiler/rustc_error_codes/src/error_codes/E0463.md b/compiler/rustc_error_codes/src/error_codes/E0463.md index e46938c607d34..d0cd1b1dcb75b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0463.md +++ b/compiler/rustc_error_codes/src/error_codes/E0463.md @@ -11,3 +11,24 @@ extern crate cake_is_a_lie; // error: can't find crate for `cake_is_a_lie` You need to link your code to the relevant crate in order to be able to use it (through Cargo or the `-L` option of rustc example). Plugins are crates as well, and you link to them the same way. + +## Common causes + +- The crate is not present at all. If using Cargo, add it to `[dependencies]` + in Cargo.toml. +- The crate is present, but under a different name. If using Cargo, look for + `package = ` under `[dependencies]` in Cargo.toml. + +## Common causes for missing `std` or `core` + +- You are cross-compiling for a target which doesn't have `std` prepackaged. + Consider one of the following: + + Adding a pre-compiled version of std with `rustup target add` + + Building std from source with `cargo build -Z build-std` + + Using `#![no_std]` at the crate root, so you won't need `std` in the first + place. +- You are developing the compiler itself and haven't built libstd from source. + You can usually build it with `x.py build library/std`. More information + about x.py is available in the [rustc-dev-guide]. + +[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#building-the-compiler From 3b5d018ebb6ee8aa6181ebf1cf9ba0cb407f622f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Jan 2021 12:48:31 -0800 Subject: [PATCH 12/26] Handle `Span`s for byte and raw strings and add more detail --- compiler/rustc_parse/src/lexer/mod.rs | 30 ++- .../src/lexer/unescape_error_reporting.rs | 186 +++++++++++------- src/test/ui/attributes/key-value-non-ascii.rs | 2 +- .../ui/attributes/key-value-non-ascii.stderr | 5 +- .../ui/parser/ascii-only-character-escape.rs | 6 +- .../parser/ascii-only-character-escape.stderr | 12 +- src/test/ui/parser/bad-char-literals.rs | 8 +- src/test/ui/parser/bad-char-literals.stderr | 16 +- src/test/ui/parser/byte-literals.rs | 4 +- src/test/ui/parser/byte-literals.stderr | 25 ++- src/test/ui/parser/byte-string-literals.rs | 5 +- .../ui/parser/byte-string-literals.stderr | 27 ++- .../ui/parser/issue-23620-invalid-escapes.rs | 14 +- .../parser/issue-23620-invalid-escapes.stderr | 34 ++-- src/test/ui/parser/issue-43692.stderr | 4 +- src/test/ui/parser/issue-62913.stderr | 2 +- src/test/ui/parser/issue-64732.stderr | 6 +- .../ui/parser/lex-bad-char-literals-1.stderr | 8 +- src/test/ui/parser/lex-bad-char-literals-7.rs | 2 +- .../ui/parser/lex-bad-char-literals-7.stderr | 6 +- .../lex-bare-cr-string-literal-doc-comment.rs | 2 +- ...-bare-cr-string-literal-doc-comment.stderr | 6 +- ...rals-are-validated-before-expansion.stderr | 4 +- src/test/ui/parser/new-unicode-escapes-1.rs | 2 +- .../ui/parser/new-unicode-escapes-1.stderr | 9 +- src/test/ui/parser/new-unicode-escapes-2.rs | 2 +- .../ui/parser/new-unicode-escapes-2.stderr | 4 +- .../ui/parser/new-unicode-escapes-3.stderr | 4 +- src/test/ui/parser/new-unicode-escapes-4.rs | 2 +- .../ui/parser/new-unicode-escapes-4.stderr | 4 +- .../raw/raw-byte-string-literals.stderr | 2 +- .../trailing-carriage-return-in-string.rs | 4 +- .../trailing-carriage-return-in-string.stderr | 2 +- .../ui/parser/wrong-escape-of-curly-braces.rs | 8 +- .../wrong-escape-of-curly-braces.stderr | 4 +- 35 files changed, 278 insertions(+), 183 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index b5b34c7338d88..4a638ec3f8020 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -14,7 +14,7 @@ mod tokentrees; mod unescape_error_reporting; mod unicode_chars; -use unescape_error_reporting::{emit_unescape_error, push_escaped_char}; +use unescape_error_reporting::{emit_unescape_error, escaped_char}; #[derive(Clone, Debug)] pub struct UnmatchedBrace { @@ -122,11 +122,9 @@ impl<'a> StringReader<'a> { m: &str, c: char, ) -> DiagnosticBuilder<'a> { - let mut m = m.to_string(); - m.push_str(": "); - push_escaped_char(&mut m, c); - - self.sess.span_diagnostic.struct_span_fatal(self.mk_sp(from_pos, to_pos), &m[..]) + self.sess + .span_diagnostic + .struct_span_fatal(self.mk_sp(from_pos, to_pos), &format!("{}: {}", m, escaped_char(c))) } /// Turns simple `rustc_lexer::TokenKind` enum into a rich @@ -421,7 +419,7 @@ impl<'a> StringReader<'a> { let content_start = start + BytePos(prefix_len); let content_end = suffix_start - BytePos(postfix_len); let id = self.symbol_from_to(content_start, content_end); - self.validate_literal_escape(mode, content_start, content_end); + self.validate_literal_escape(mode, content_start, content_end, prefix_len, postfix_len); (lit_kind, id) } @@ -525,17 +523,29 @@ impl<'a> StringReader<'a> { .raise(); } - fn validate_literal_escape(&self, mode: Mode, content_start: BytePos, content_end: BytePos) { + fn validate_literal_escape( + &self, + mode: Mode, + content_start: BytePos, + content_end: BytePos, + prefix_len: u32, + postfix_len: u32, + ) { let lit_content = self.str_from_to(content_start, content_end); unescape::unescape_literal(lit_content, mode, &mut |range, result| { // Here we only check for errors. The actual unescaping is done later. if let Err(err) = result { - let span_with_quotes = - self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)); + let span_with_quotes = self + .mk_sp(content_start - BytePos(prefix_len), content_end + BytePos(postfix_len)); + let (start, end) = (range.start as u32, range.end as u32); + let lo = content_start + BytePos(start); + let hi = lo + BytePos(end - start); + let span = self.mk_sp(lo, hi); emit_unescape_error( &self.sess.span_diagnostic, lit_content, span_with_quotes, + span, mode, range, err, diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 47d317f918865..a580f0c55d0e3 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -13,6 +13,8 @@ pub(crate) fn emit_unescape_error( lit: &str, // full span of the literal, including quotes span_with_quotes: Span, + // interior span of the literal, without quotes + span: Span, mode: Mode, // range of the error inside `lit` range: Range, @@ -26,13 +28,6 @@ pub(crate) fn emit_unescape_error( range, error ); - let span = { - let Range { start, end } = range; - let (start, end) = (start as u32, end as u32); - let lo = span_with_quotes.lo() + BytePos(start + 1); - let hi = lo + BytePos(end - start); - span_with_quotes.with_lo(lo).with_hi(hi) - }; let last_char = || { let c = lit[range.clone()].chars().rev().next().unwrap(); let span = span.with_lo(span.hi() - BytePos(c.len_utf8() as u32)); @@ -42,20 +37,22 @@ pub(crate) fn emit_unescape_error( EscapeError::LoneSurrogateUnicodeEscape => { handler .struct_span_err(span, "invalid unicode character escape") + .span_label(span, "invalid escape") .help("unicode escape must not be a surrogate") .emit(); } EscapeError::OutOfRangeUnicodeEscape => { handler .struct_span_err(span, "invalid unicode character escape") + .span_label(span, "invalid escape") .help("unicode escape must be at most 10FFFF") .emit(); } EscapeError::MoreThanOneChar => { - let msg = if mode.is_bytes() { - "if you meant to write a byte string literal, use double quotes" + let (prefix, msg) = if mode.is_bytes() { + ("b", "if you meant to write a byte string literal, use double quotes") } else { - "if you meant to write a `str` literal, use double quotes" + ("", "if you meant to write a `str` literal, use double quotes") }; handler @@ -66,31 +63,44 @@ pub(crate) fn emit_unescape_error( .span_suggestion( span_with_quotes, msg, - format!("\"{}\"", lit), + format!("{}\"{}\"", prefix, lit), Applicability::MachineApplicable, ) .emit(); } EscapeError::EscapeOnlyChar => { - let (c, _span) = last_char(); + let (c, char_span) = last_char(); - let mut msg = if mode.is_bytes() { - "byte constant must be escaped: " + let msg = if mode.is_bytes() { + "byte constant must be escaped" } else { - "character constant must be escaped: " - } - .to_string(); - push_escaped_char(&mut msg, c); - - handler.span_err(span, msg.as_str()) + "character constant must be escaped" + }; + handler + .struct_span_err(span, &format!("{}: `{}`", msg, escaped_char(c))) + .span_suggestion( + char_span, + "escape the character", + c.escape_default().to_string(), + Applicability::MachineApplicable, + ) + .emit() } EscapeError::BareCarriageReturn => { let msg = if mode.in_double_quotes() { - "bare CR not allowed in string, use \\r instead" + "bare CR not allowed in string, use `\\r` instead" } else { - "character constant must be escaped: \\r" + "character constant must be escaped: `\\r`" }; - handler.span_err(span, msg); + handler + .struct_span_err(span, msg) + .span_suggestion( + span, + "escape the character", + "\\r".to_string(), + Applicability::MachineApplicable, + ) + .emit(); } EscapeError::BareCarriageReturnInRawString => { assert!(mode.in_double_quotes()); @@ -102,21 +112,22 @@ pub(crate) fn emit_unescape_error( let label = if mode.is_bytes() { "unknown byte escape" } else { "unknown character escape" }; - let mut msg = label.to_string(); - msg.push_str(": "); - push_escaped_char(&mut msg, c); - - let mut diag = handler.struct_span_err(span, msg.as_str()); + let ec = escaped_char(c); + let mut diag = handler.struct_span_err(span, &format!("{}: `{}`", label, ec)); diag.span_label(span, label); if c == '{' || c == '}' && !mode.is_bytes() { diag.help( - "if used in a formatting string, \ - curly braces are escaped with `{{` and `}}`", + "if used in a formatting string, curly braces are escaped with `{{` and `}}`", ); } else if c == '\r' { diag.help( - "this is an isolated carriage return; \ - consider checking your editor and version control settings", + "this is an isolated carriage return; consider checking your editor and \ + version control settings", + ); + } else { + diag.help( + "for more information, visit \ + ", ); } diag.emit(); @@ -127,45 +138,70 @@ pub(crate) fn emit_unescape_error( EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => { let (c, span) = last_char(); - let mut msg = if error == EscapeError::InvalidCharInHexEscape { - "invalid character in numeric character escape: " + let msg = if error == EscapeError::InvalidCharInHexEscape { + "invalid character in numeric character escape" } else { - "invalid character in unicode escape: " - } - .to_string(); - push_escaped_char(&mut msg, c); + "invalid character in unicode escape" + }; + let c = escaped_char(c); - handler.span_err(span, msg.as_str()) + handler + .struct_span_err(span, &format!("{}: `{}`", msg, c)) + .span_label(span, msg) + .emit(); } EscapeError::NonAsciiCharInByte => { assert!(mode.is_bytes()); - let (_c, span) = last_char(); - handler.span_err( - span, - "byte constant must be ASCII. \ - Use a \\xHH escape for a non-ASCII byte", - ) + let (c, span) = last_char(); + handler + .struct_span_err(span, "non-ASCII character in byte constant") + .span_label(span, "byte constant must be ASCII") + .span_suggestion( + span, + "use a \\xHH escape for a non-ASCII byte", + format!("\\x{:X}", c as u32), + Applicability::MachineApplicable, + ) + .emit(); } EscapeError::NonAsciiCharInByteString => { assert!(mode.is_bytes()); let (_c, span) = last_char(); - handler.span_err(span, "raw byte string must be ASCII") + handler + .struct_span_err(span, "raw byte string must be ASCII") + .span_label(span, "must be ASCII") + .emit(); + } + EscapeError::OutOfRangeHexEscape => { + handler + .struct_span_err(span, "out of range hex escape") + .span_label(span, "must be a character in the range [\\x00-\\x7f]") + .emit(); } - EscapeError::OutOfRangeHexEscape => handler.span_err( - span, - "this form of character escape may only be used \ - with characters in the range [\\x00-\\x7f]", - ), EscapeError::LeadingUnderscoreUnicodeEscape => { - let (_c, span) = last_char(); - handler.span_err(span, "invalid start of unicode escape") + let (c, span) = last_char(); + let msg = "invalid start of unicode escape"; + handler + .struct_span_err(span, &format!("{}: `{}`", msg, c)) + .span_label(span, msg) + .emit(); } EscapeError::OverlongUnicodeEscape => { - handler.span_err(span, "overlong unicode escape (must have at most 6 hex digits)") - } - EscapeError::UnclosedUnicodeEscape => { - handler.span_err(span, "unterminated unicode escape (needed a `}`)") + handler + .struct_span_err(span, "overlong unicode escape") + .span_label(span, "must have at most 6 hex digits") + .emit(); } + EscapeError::UnclosedUnicodeEscape => handler + .struct_span_err(span, "unterminated unicode escape") + .span_label(span, "missing a closing `}`") + .span_suggestion_verbose( + span.shrink_to_hi(), + "terminate the unicode escape", + "}".to_string(), + Applicability::MaybeIncorrect, + ) + .emit(), EscapeError::NoBraceInUnicodeEscape => { let msg = "incorrect unicode escape sequence"; let mut diag = handler.struct_span_err(span, msg); @@ -195,28 +231,38 @@ pub(crate) fn emit_unescape_error( diag.emit(); } - EscapeError::UnicodeEscapeInByte => handler.span_err( - span, - "unicode escape sequences cannot be used \ - as a byte or in a byte string", - ), + EscapeError::UnicodeEscapeInByte => { + let msg = "unicode escape in byte string"; + handler + .struct_span_err(span, msg) + .span_label(span, msg) + .help("unicode escape sequences cannot be used as a byte or in a byte string") + .emit(); + } EscapeError::EmptyUnicodeEscape => { - handler.span_err(span, "empty unicode escape (must have at least 1 hex digit)") + handler + .struct_span_err(span, "empty unicode escape") + .span_label(span, "this escape must have at least 1 hex digit") + .emit(); + } + EscapeError::ZeroChars => { + let msg = "empty character literal"; + handler.struct_span_err(span, msg).span_label(span, msg).emit() + } + EscapeError::LoneSlash => { + let msg = "invalid trailing slash in literal"; + handler.struct_span_err(span, msg).span_label(span, msg).emit(); } - EscapeError::ZeroChars => handler.span_err(span, "empty character literal"), - EscapeError::LoneSlash => handler.span_err(span, "invalid trailing slash in literal"), } } /// Pushes a character to a message string for error reporting -pub(crate) fn push_escaped_char(msg: &mut String, c: char) { +pub(crate) fn escaped_char(c: char) -> String { match c { '\u{20}'..='\u{7e}' => { // Don't escape \, ' or " for user-facing messages - msg.push(c); - } - _ => { - msg.extend(c.escape_default()); + c.to_string() } + _ => c.escape_default().to_string(), } } diff --git a/src/test/ui/attributes/key-value-non-ascii.rs b/src/test/ui/attributes/key-value-non-ascii.rs index 91c917e7db56f..12942eabdf7b5 100644 --- a/src/test/ui/attributes/key-value-non-ascii.rs +++ b/src/test/ui/attributes/key-value-non-ascii.rs @@ -1,4 +1,4 @@ #![feature(rustc_attrs)] -#[rustc_dummy = b"ffi.rs"] //~ ERROR byte constant must be ASCII +#[rustc_dummy = b"ffi.rs"] //~ ERROR non-ASCII character in byte constant fn main() {} diff --git a/src/test/ui/attributes/key-value-non-ascii.stderr b/src/test/ui/attributes/key-value-non-ascii.stderr index 3e082139f895b..1d4b0d5b2b130 100644 --- a/src/test/ui/attributes/key-value-non-ascii.stderr +++ b/src/test/ui/attributes/key-value-non-ascii.stderr @@ -1,8 +1,11 @@ -error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte +error: non-ASCII character in byte constant --> $DIR/key-value-non-ascii.rs:3:19 | LL | #[rustc_dummy = b"ffi.rs"] | ^ + | | + | byte constant must be ASCII + | help: use a \xHH escape for a non-ASCII byte: `\xFB03` error: aborting due to previous error diff --git a/src/test/ui/parser/ascii-only-character-escape.rs b/src/test/ui/parser/ascii-only-character-escape.rs index 20d3edf125175..725c8ad23515e 100644 --- a/src/test/ui/parser/ascii-only-character-escape.rs +++ b/src/test/ui/parser/ascii-only-character-escape.rs @@ -1,6 +1,6 @@ fn main() { - let x = "\x80"; //~ ERROR may only be used - let y = "\xff"; //~ ERROR may only be used - let z = "\xe2"; //~ ERROR may only be used + let x = "\x80"; //~ ERROR out of range hex escape + let y = "\xff"; //~ ERROR out of range hex escape + let z = "\xe2"; //~ ERROR out of range hex escape let a = b"\x00e2"; // ok because byte literal } diff --git a/src/test/ui/parser/ascii-only-character-escape.stderr b/src/test/ui/parser/ascii-only-character-escape.stderr index cf51b00cdc39a..b599b35f4b324 100644 --- a/src/test/ui/parser/ascii-only-character-escape.stderr +++ b/src/test/ui/parser/ascii-only-character-escape.stderr @@ -1,20 +1,20 @@ -error: this form of character escape may only be used with characters in the range [\x00-\x7f] +error: out of range hex escape --> $DIR/ascii-only-character-escape.rs:2:14 | LL | let x = "\x80"; - | ^^^^ + | ^^^^ must be a character in the range [\x00-\x7f] -error: this form of character escape may only be used with characters in the range [\x00-\x7f] +error: out of range hex escape --> $DIR/ascii-only-character-escape.rs:3:14 | LL | let y = "\xff"; - | ^^^^ + | ^^^^ must be a character in the range [\x00-\x7f] -error: this form of character escape may only be used with characters in the range [\x00-\x7f] +error: out of range hex escape --> $DIR/ascii-only-character-escape.rs:4:14 | LL | let z = "\xe2"; - | ^^^^ + | ^^^^ must be a character in the range [\x00-\x7f] error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/bad-char-literals.rs b/src/test/ui/parser/bad-char-literals.rs index 11696b82bc9ac..748b4a22253f5 100644 --- a/src/test/ui/parser/bad-char-literals.rs +++ b/src/test/ui/parser/bad-char-literals.rs @@ -4,17 +4,17 @@ fn main() { // these literals are just silly. '''; - //~^ ERROR: character constant must be escaped: ' + //~^ ERROR: character constant must be escaped: `'` // note that this is a literal "\n" byte ' '; - //~^^ ERROR: character constant must be escaped: \n + //~^^ ERROR: character constant must be escaped: `\n` // note that this is a literal "\r" byte - ' '; //~ ERROR: character constant must be escaped: \r + ' '; //~ ERROR: character constant must be escaped: `\r` // note that this is a literal tab character here ' '; - //~^ ERROR: character constant must be escaped: \t + //~^ ERROR: character constant must be escaped: `\t` } diff --git a/src/test/ui/parser/bad-char-literals.stderr b/src/test/ui/parser/bad-char-literals.stderr index 093978fd84d00..a22ddbac1b931 100644 --- a/src/test/ui/parser/bad-char-literals.stderr +++ b/src/test/ui/parser/bad-char-literals.stderr @@ -1,28 +1,28 @@ -error: character constant must be escaped: ' +error: character constant must be escaped: `'` --> $DIR/bad-char-literals.rs:6:6 | LL | '''; - | ^ + | ^ help: escape the character: `\'` -error: character constant must be escaped: \n +error: character constant must be escaped: `\n` --> $DIR/bad-char-literals.rs:10:6 | LL | ' | ______^ LL | | '; - | |_ + | |_ help: escape the character: `\n` -error: character constant must be escaped: \r +error: character constant must be escaped: `\r` --> $DIR/bad-char-literals.rs:15:6 | LL | ' '; - | ^ + | ^ help: escape the character: `\r` -error: character constant must be escaped: \t +error: character constant must be escaped: `\t` --> $DIR/bad-char-literals.rs:18:6 | LL | ' '; - | ^^^^ + | ^^^^ help: escape the character: `\t` error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/byte-literals.rs b/src/test/ui/parser/byte-literals.rs index 9683a83e72095..05a510b24a7ab 100644 --- a/src/test/ui/parser/byte-literals.rs +++ b/src/test/ui/parser/byte-literals.rs @@ -4,9 +4,9 @@ static FOO: u8 = b'\f'; //~ ERROR unknown byte escape pub fn main() { b'\f'; //~ ERROR unknown byte escape - b'\x0Z'; //~ ERROR invalid character in numeric character escape: Z + b'\x0Z'; //~ ERROR invalid character in numeric character escape: `Z` b' '; //~ ERROR byte constant must be escaped b'''; //~ ERROR byte constant must be escaped - b'é'; //~ ERROR byte constant must be ASCII + b'é'; //~ ERROR non-ASCII character in byte constant b'a //~ ERROR unterminated byte constant [E0763] } diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr index 7bbdc07cd835f..55be113e16b99 100644 --- a/src/test/ui/parser/byte-literals.stderr +++ b/src/test/ui/parser/byte-literals.stderr @@ -1,38 +1,45 @@ -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-literals.rs:3:21 | LL | static FOO: u8 = b'\f'; | ^ unknown byte escape + | + = help: for more information, visit -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-literals.rs:6:8 | LL | b'\f'; | ^ unknown byte escape + | + = help: for more information, visit -error: invalid character in numeric character escape: Z +error: invalid character in numeric character escape: `Z` --> $DIR/byte-literals.rs:7:10 | LL | b'\x0Z'; - | ^ + | ^ invalid character in numeric character escape -error: byte constant must be escaped: \t +error: byte constant must be escaped: `\t` --> $DIR/byte-literals.rs:8:7 | LL | b' '; - | ^^^^ + | ^^^^ help: escape the character: `\t` -error: byte constant must be escaped: ' +error: byte constant must be escaped: `'` --> $DIR/byte-literals.rs:9:7 | LL | b'''; - | ^ + | ^ help: escape the character: `\'` -error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte +error: non-ASCII character in byte constant --> $DIR/byte-literals.rs:10:7 | LL | b'é'; | ^ + | | + | byte constant must be ASCII + | help: use a \xHH escape for a non-ASCII byte: `\xE9` error[E0763]: unterminated byte constant --> $DIR/byte-literals.rs:11:6 diff --git a/src/test/ui/parser/byte-string-literals.rs b/src/test/ui/parser/byte-string-literals.rs index caffd9efbed37..b1f11024a7bb6 100644 --- a/src/test/ui/parser/byte-string-literals.rs +++ b/src/test/ui/parser/byte-string-literals.rs @@ -2,7 +2,8 @@ static FOO: &'static [u8] = b"\f"; //~ ERROR unknown byte escape pub fn main() { b"\f"; //~ ERROR unknown byte escape - b"\x0Z"; //~ ERROR invalid character in numeric character escape: Z - b"é"; //~ ERROR byte constant must be ASCII + b"\x0Z"; //~ ERROR invalid character in numeric character escape: `Z` + b"é"; //~ ERROR non-ASCII character in byte constant + br##"é"##; //~ ERROR raw byte string must be ASCII b"a //~ ERROR unterminated double quote byte string } diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr index 9be9064414796..3a5a8b331d339 100644 --- a/src/test/ui/parser/byte-string-literals.stderr +++ b/src/test/ui/parser/byte-string-literals.stderr @@ -1,35 +1,48 @@ -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:1:32 | LL | static FOO: &'static [u8] = b"\f"; | ^ unknown byte escape + | + = help: for more information, visit -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:4:8 | LL | b"\f"; | ^ unknown byte escape + | + = help: for more information, visit -error: invalid character in numeric character escape: Z +error: invalid character in numeric character escape: `Z` --> $DIR/byte-string-literals.rs:5:10 | LL | b"\x0Z"; - | ^ + | ^ invalid character in numeric character escape -error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte +error: non-ASCII character in byte constant --> $DIR/byte-string-literals.rs:6:7 | LL | b"é"; | ^ + | | + | byte constant must be ASCII + | help: use a \xHH escape for a non-ASCII byte: `\xE9` + +error: raw byte string must be ASCII + --> $DIR/byte-string-literals.rs:7:10 + | +LL | br##"é"##; + | ^ must be ASCII error[E0766]: unterminated double quote byte string - --> $DIR/byte-string-literals.rs:7:6 + --> $DIR/byte-string-literals.rs:8:6 | LL | b"a | ______^ LL | | } | |__^ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0766`. diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.rs b/src/test/ui/parser/issue-23620-invalid-escapes.rs index ab445a9329426..c1355f0d6fe0c 100644 --- a/src/test/ui/parser/issue-23620-invalid-escapes.rs +++ b/src/test/ui/parser/issue-23620-invalid-escapes.rs @@ -1,9 +1,9 @@ fn main() { let _ = b"\u{a66e}"; - //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string + //~^ ERROR unicode escape in byte string let _ = b'\u{a66e}'; - //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string + //~^ ERROR unicode escape in byte string let _ = b'\u'; //~^ ERROR incorrect unicode escape sequence @@ -12,21 +12,21 @@ fn main() { //~^ ERROR numeric character escape is too short let _ = b'\xxy'; - //~^ ERROR invalid character in numeric character escape: x + //~^ ERROR invalid character in numeric character escape: `x` let _ = '\x5'; //~^ ERROR numeric character escape is too short let _ = '\xxy'; - //~^ ERROR invalid character in numeric character escape: x + //~^ ERROR invalid character in numeric character escape: `x` let _ = b"\u{a4a4} \xf \u"; - //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string - //~^^ ERROR invalid character in numeric character escape: + //~^ ERROR unicode escape in byte string + //~^^ ERROR invalid character in numeric character escape: ` ` //~^^^ ERROR incorrect unicode escape sequence let _ = "\xf \u"; - //~^ ERROR invalid character in numeric character escape: + //~^ ERROR invalid character in numeric character escape: ` ` //~^^ ERROR incorrect unicode escape sequence let _ = "\u8f"; diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.stderr b/src/test/ui/parser/issue-23620-invalid-escapes.stderr index 8c924ad0330e9..88d97c795fc2a 100644 --- a/src/test/ui/parser/issue-23620-invalid-escapes.stderr +++ b/src/test/ui/parser/issue-23620-invalid-escapes.stderr @@ -1,14 +1,18 @@ -error: unicode escape sequences cannot be used as a byte or in a byte string +error: unicode escape in byte string --> $DIR/issue-23620-invalid-escapes.rs:2:15 | LL | let _ = b"\u{a66e}"; - | ^^^^^^^^ + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string -error: unicode escape sequences cannot be used as a byte or in a byte string +error: unicode escape in byte string --> $DIR/issue-23620-invalid-escapes.rs:5:15 | LL | let _ = b'\u{a66e}'; - | ^^^^^^^^ + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:8:15 @@ -24,11 +28,11 @@ error: numeric character escape is too short LL | let _ = b'\x5'; | ^^^ -error: invalid character in numeric character escape: x +error: invalid character in numeric character escape: `x` --> $DIR/issue-23620-invalid-escapes.rs:14:17 | LL | let _ = b'\xxy'; - | ^ + | ^ invalid character in numeric character escape error: numeric character escape is too short --> $DIR/issue-23620-invalid-escapes.rs:17:14 @@ -36,23 +40,25 @@ error: numeric character escape is too short LL | let _ = '\x5'; | ^^^ -error: invalid character in numeric character escape: x +error: invalid character in numeric character escape: `x` --> $DIR/issue-23620-invalid-escapes.rs:20:16 | LL | let _ = '\xxy'; - | ^ + | ^ invalid character in numeric character escape -error: unicode escape sequences cannot be used as a byte or in a byte string +error: unicode escape in byte string --> $DIR/issue-23620-invalid-escapes.rs:23:15 | LL | let _ = b"\u{a4a4} \xf \u"; - | ^^^^^^^^ + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string -error: invalid character in numeric character escape: +error: invalid character in numeric character escape: ` ` --> $DIR/issue-23620-invalid-escapes.rs:23:27 | LL | let _ = b"\u{a4a4} \xf \u"; - | ^ + | ^ invalid character in numeric character escape error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:23:28 @@ -62,11 +68,11 @@ LL | let _ = b"\u{a4a4} \xf \u"; | = help: format of unicode escape sequences is `\u{...}` -error: invalid character in numeric character escape: +error: invalid character in numeric character escape: ` ` --> $DIR/issue-23620-invalid-escapes.rs:28:17 | LL | let _ = "\xf \u"; - | ^ + | ^ invalid character in numeric character escape error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:28:18 diff --git a/src/test/ui/parser/issue-43692.stderr b/src/test/ui/parser/issue-43692.stderr index 69a54af3d82ed..baf998035178b 100644 --- a/src/test/ui/parser/issue-43692.stderr +++ b/src/test/ui/parser/issue-43692.stderr @@ -1,8 +1,8 @@ -error: invalid start of unicode escape +error: invalid start of unicode escape: `_` --> $DIR/issue-43692.rs:2:9 | LL | '\u{_10FFFF}'; - | ^ + | ^ invalid start of unicode escape error: aborting due to previous error diff --git a/src/test/ui/parser/issue-62913.stderr b/src/test/ui/parser/issue-62913.stderr index f72174f8929b8..6f385e8dc1777 100644 --- a/src/test/ui/parser/issue-62913.stderr +++ b/src/test/ui/parser/issue-62913.stderr @@ -10,7 +10,7 @@ error: invalid trailing slash in literal --> $DIR/issue-62913.rs:1:5 | LL | "\u\" - | ^ + | ^ invalid trailing slash in literal error: expected item, found `"\u\"` --> $DIR/issue-62913.rs:1:1 diff --git a/src/test/ui/parser/issue-64732.stderr b/src/test/ui/parser/issue-64732.stderr index 3b00ffc8f6c8d..ac04258096280 100644 --- a/src/test/ui/parser/issue-64732.stderr +++ b/src/test/ui/parser/issue-64732.stderr @@ -1,13 +1,13 @@ error: character literal may only contain one codepoint - --> $DIR/issue-64732.rs:3:17 + --> $DIR/issue-64732.rs:3:16 | LL | let _foo = b'hello\0'; - | ^^^^^^^^^ + | ^^^^^^^^^^ | help: if you meant to write a byte string literal, use double quotes | LL | let _foo = b"hello\0"; - | ^^^^^^^^^ + | ^^^^^^^^^^ error: character literal may only contain one codepoint --> $DIR/issue-64732.rs:6:16 diff --git a/src/test/ui/parser/lex-bad-char-literals-1.stderr b/src/test/ui/parser/lex-bad-char-literals-1.stderr index fcf4802f79bba..ed129a1d13388 100644 --- a/src/test/ui/parser/lex-bad-char-literals-1.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-1.stderr @@ -10,17 +10,21 @@ error: numeric character escape is too short LL | "\x1" | ^^^ -error: unknown character escape: \u{25cf} +error: unknown character escape: `\u{25cf}` --> $DIR/lex-bad-char-literals-1.rs:10:7 | LL | '\●' | ^ unknown character escape + | + = help: for more information, visit -error: unknown character escape: \u{25cf} +error: unknown character escape: `\u{25cf}` --> $DIR/lex-bad-char-literals-1.rs:14:7 | LL | "\●" | ^ unknown character escape + | + = help: for more information, visit error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/lex-bad-char-literals-7.rs b/src/test/ui/parser/lex-bad-char-literals-7.rs index 1580157210e69..c675df2f3ccd0 100644 --- a/src/test/ui/parser/lex-bad-char-literals-7.rs +++ b/src/test/ui/parser/lex-bad-char-literals-7.rs @@ -2,7 +2,7 @@ fn main() { let _: char = ''; //~^ ERROR: empty character literal let _: char = '\u{}'; - //~^ ERROR: empty unicode escape (must have at least 1 hex digit) + //~^ ERROR: empty unicode escape // Next two are OK, but may befool error recovery let _ = '/'; diff --git a/src/test/ui/parser/lex-bad-char-literals-7.stderr b/src/test/ui/parser/lex-bad-char-literals-7.stderr index 70ee8087b5163..255b9c6899999 100644 --- a/src/test/ui/parser/lex-bad-char-literals-7.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-7.stderr @@ -2,13 +2,13 @@ error: empty character literal --> $DIR/lex-bad-char-literals-7.rs:2:20 | LL | let _: char = ''; - | ^ + | ^ empty character literal -error: empty unicode escape (must have at least 1 hex digit) +error: empty unicode escape --> $DIR/lex-bad-char-literals-7.rs:4:20 | LL | let _: char = '\u{}'; - | ^^^^ + | ^^^^ this escape must have at least 1 hex digit error[E0762]: unterminated character literal --> $DIR/lex-bad-char-literals-7.rs:11:13 diff --git a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs index 9a9f9c433e1d6..b7752e1f0c45f 100644 --- a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs +++ b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs @@ -22,5 +22,5 @@ fn main() { let _s = r"bar foo"; //~ ERROR: bare CR not allowed in raw string // the following string literal has a bare CR in it - let _s = "foo\ bar"; //~ ERROR: unknown character escape: \r + let _s = "foo\ bar"; //~ ERROR: unknown character escape: `\r` } diff --git a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr index 598da6b930730..1a21fed63bdec 100644 --- a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr +++ b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr @@ -22,11 +22,11 @@ error: bare CR not allowed in block doc-comment LL | /*! block doc comment with bare CR: ' ' */ | ^ -error: bare CR not allowed in string, use \r instead +error: bare CR not allowed in string, use `\r` instead --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:19:18 | LL | let _s = "foo bar"; - | ^ + | ^ help: escape the character: `\r` error: bare CR not allowed in raw string --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:22:19 @@ -34,7 +34,7 @@ error: bare CR not allowed in raw string LL | let _s = r"bar foo"; | ^ -error: unknown character escape: \r +error: unknown character escape: `\r` --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:25:19 | LL | let _s = "foo\ bar"; diff --git a/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr index d20eb0fb30a49..e874f62497ea8 100644 --- a/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr +++ b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr @@ -2,7 +2,7 @@ error: invalid unicode character escape --> $DIR/literals-are-validated-before-expansion.rs:6:20 | LL | black_hole! { '\u{FFFFFF}' } - | ^^^^^^^^^^ + | ^^^^^^^^^^ invalid escape | = help: unicode escape must be at most 10FFFF @@ -10,7 +10,7 @@ error: invalid unicode character escape --> $DIR/literals-are-validated-before-expansion.rs:8:39 | LL | black_hole! { "this is surrogate: \u{DAAA}" } - | ^^^^^^^^ + | ^^^^^^^^ invalid escape | = help: unicode escape must not be a surrogate diff --git a/src/test/ui/parser/new-unicode-escapes-1.rs b/src/test/ui/parser/new-unicode-escapes-1.rs index 0e1421214d9d8..d6a54660ea6e8 100644 --- a/src/test/ui/parser/new-unicode-escapes-1.rs +++ b/src/test/ui/parser/new-unicode-escapes-1.rs @@ -1,3 +1,3 @@ pub fn main() { - let s = "\u{2603"; //~ ERROR unterminated unicode escape (needed a `}`) + let s = "\u{2603"; //~ ERROR unterminated unicode escape } diff --git a/src/test/ui/parser/new-unicode-escapes-1.stderr b/src/test/ui/parser/new-unicode-escapes-1.stderr index 22d6a0981ffd6..1ffdc0401e59c 100644 --- a/src/test/ui/parser/new-unicode-escapes-1.stderr +++ b/src/test/ui/parser/new-unicode-escapes-1.stderr @@ -1,8 +1,13 @@ -error: unterminated unicode escape (needed a `}`) +error: unterminated unicode escape --> $DIR/new-unicode-escapes-1.rs:2:14 | LL | let s = "\u{2603"; - | ^^^^^^^ + | ^^^^^^^ missing a closing `}` + | +help: terminate the unicode escape + | +LL | let s = "\u{2603}"; + | ^ error: aborting due to previous error diff --git a/src/test/ui/parser/new-unicode-escapes-2.rs b/src/test/ui/parser/new-unicode-escapes-2.rs index b30b3dbf9036a..cbb614c19c004 100644 --- a/src/test/ui/parser/new-unicode-escapes-2.rs +++ b/src/test/ui/parser/new-unicode-escapes-2.rs @@ -1,3 +1,3 @@ pub fn main() { - let s = "\u{260311111111}"; //~ ERROR overlong unicode escape (must have at most 6 hex digits) + let s = "\u{260311111111}"; //~ ERROR overlong unicode escape } diff --git a/src/test/ui/parser/new-unicode-escapes-2.stderr b/src/test/ui/parser/new-unicode-escapes-2.stderr index b5148279c7450..2f3f8c0f9dae5 100644 --- a/src/test/ui/parser/new-unicode-escapes-2.stderr +++ b/src/test/ui/parser/new-unicode-escapes-2.stderr @@ -1,8 +1,8 @@ -error: overlong unicode escape (must have at most 6 hex digits) +error: overlong unicode escape --> $DIR/new-unicode-escapes-2.rs:2:14 | LL | let s = "\u{260311111111}"; - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ must have at most 6 hex digits error: aborting due to previous error diff --git a/src/test/ui/parser/new-unicode-escapes-3.stderr b/src/test/ui/parser/new-unicode-escapes-3.stderr index 361698467f97d..f5a0f8fc785c5 100644 --- a/src/test/ui/parser/new-unicode-escapes-3.stderr +++ b/src/test/ui/parser/new-unicode-escapes-3.stderr @@ -2,7 +2,7 @@ error: invalid unicode character escape --> $DIR/new-unicode-escapes-3.rs:2:15 | LL | let s1 = "\u{d805}"; - | ^^^^^^^^ + | ^^^^^^^^ invalid escape | = help: unicode escape must not be a surrogate @@ -10,7 +10,7 @@ error: invalid unicode character escape --> $DIR/new-unicode-escapes-3.rs:3:15 | LL | let s2 = "\u{ffffff}"; - | ^^^^^^^^^^ + | ^^^^^^^^^^ invalid escape | = help: unicode escape must be at most 10FFFF diff --git a/src/test/ui/parser/new-unicode-escapes-4.rs b/src/test/ui/parser/new-unicode-escapes-4.rs index 9ac03cedc3f3e..79882713e59a2 100644 --- a/src/test/ui/parser/new-unicode-escapes-4.rs +++ b/src/test/ui/parser/new-unicode-escapes-4.rs @@ -1,4 +1,4 @@ pub fn main() { let s = "\u{lol}"; - //~^ ERROR invalid character in unicode escape: l + //~^ ERROR invalid character in unicode escape: `l` } diff --git a/src/test/ui/parser/new-unicode-escapes-4.stderr b/src/test/ui/parser/new-unicode-escapes-4.stderr index a35c5f0f21658..514591af17e6e 100644 --- a/src/test/ui/parser/new-unicode-escapes-4.stderr +++ b/src/test/ui/parser/new-unicode-escapes-4.stderr @@ -1,8 +1,8 @@ -error: invalid character in unicode escape: l +error: invalid character in unicode escape: `l` --> $DIR/new-unicode-escapes-4.rs:2:17 | LL | let s = "\u{lol}"; - | ^ + | ^ invalid character in unicode escape error: aborting due to previous error diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr index 4076fe334e653..cfc877104bd9f 100644 --- a/src/test/ui/parser/raw/raw-byte-string-literals.stderr +++ b/src/test/ui/parser/raw/raw-byte-string-literals.stderr @@ -8,7 +8,7 @@ error: raw byte string must be ASCII --> $DIR/raw-byte-string-literals.rs:5:8 | LL | br"é"; - | ^ + | ^ must be ASCII error: found invalid character; only `#` is allowed in raw string delimitation: ~ --> $DIR/raw-byte-string-literals.rs:6:5 diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.rs b/src/test/ui/parser/trailing-carriage-return-in-string.rs index 8abf2624e4f97..5d3c31944064a 100644 --- a/src/test/ui/parser/trailing-carriage-return-in-string.rs +++ b/src/test/ui/parser/trailing-carriage-return-in-string.rs @@ -8,7 +8,7 @@ fn main() { a test"; // \r only let bad = "This is \ a test"; - //~^ ERROR unknown character escape: \r - //~^^ HELP this is an isolated carriage return + //~^ ERROR unknown character escape: `\r` + //~| HELP this is an isolated carriage return } diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.stderr b/src/test/ui/parser/trailing-carriage-return-in-string.stderr index 3687b9dd282d1..8a44e02707ce5 100644 --- a/src/test/ui/parser/trailing-carriage-return-in-string.stderr +++ b/src/test/ui/parser/trailing-carriage-return-in-string.stderr @@ -1,4 +1,4 @@ -error: unknown character escape: \r +error: unknown character escape: `\r` --> $DIR/trailing-carriage-return-in-string.rs:10:25 | LL | let bad = "This is \ a test"; diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.rs b/src/test/ui/parser/wrong-escape-of-curly-braces.rs index 7a5c27afca552..8e5258acd49da 100644 --- a/src/test/ui/parser/wrong-escape-of-curly-braces.rs +++ b/src/test/ui/parser/wrong-escape-of-curly-braces.rs @@ -1,8 +1,8 @@ fn main() { let ok = "{{everything fine}}"; let bad = "\{it is wrong\}"; - //~^ ERROR unknown character escape: { - //~^^ HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` - //~^^^ ERROR unknown character escape: } - //~^^^^ HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` + //~^ ERROR unknown character escape: `{` + //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` + //~| ERROR unknown character escape: `}` + //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` } diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr index 1406b795ba8c3..ff1a2fb0f3c67 100644 --- a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr +++ b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr @@ -1,4 +1,4 @@ -error: unknown character escape: { +error: unknown character escape: `{` --> $DIR/wrong-escape-of-curly-braces.rs:3:17 | LL | let bad = "\{it is wrong\}"; @@ -6,7 +6,7 @@ LL | let bad = "\{it is wrong\}"; | = help: if used in a formatting string, curly braces are escaped with `{{` and `}}` -error: unknown character escape: } +error: unknown character escape: `}` --> $DIR/wrong-escape-of-curly-braces.rs:3:30 | LL | let bad = "\{it is wrong\}"; From 50e394a05e3a908e11b4cbeda28b4f8f4c0ea6ed Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Tue, 5 Jan 2021 16:33:10 +0100 Subject: [PATCH 13/26] relax adt unsizing requirements --- compiler/rustc_index/src/bit_set.rs | 12 ++++++++++++ .../src/traits/select/confirmation.rs | 13 +++++-------- src/test/ui/unsized/unchanged-param.rs | 11 +++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/unsized/unchanged-param.rs diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 0b501da7cd975..100824f4b9448 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -707,6 +707,18 @@ impl GrowableBitSet { self.bit_set.insert(elem) } + /// Returns `true` if the set has changed. + #[inline] + pub fn remove(&mut self, elem: T) -> bool { + self.ensure(elem.index() + 1); + self.bit_set.remove(elem) + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.bit_set.is_empty() + } + #[inline] pub fn contains(&self, elem: T) -> bool { let (word_index, mask) = word_index_and_mask(elem); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3015188fd447a..3e3e945f654b7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -829,16 +829,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tail_field_ty = tcx.type_of(tail_field.did); let mut unsizing_params = GrowableBitSet::new_empty(); - let mut found = false; for arg in tail_field_ty.walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.insert(i); - found = true; } } - if !found { - return Err(Unimplemented); - } // Ensure none of the other fields mention the parameters used // in unsizing. @@ -848,13 +843,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for field in prefix_fields { for arg in tcx.type_of(field.did).walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { - if unsizing_params.contains(i) { - return Err(Unimplemented); - } + unsizing_params.remove(i); } } } + if unsizing_params.is_empty() { + return Err(Unimplemented); + } + // Extract `TailField` and `TailField` from `Struct` and `Struct`. let source_tail = tail_field_ty.subst(tcx, substs_a); let target_tail = tail_field_ty.subst(tcx, substs_b); diff --git a/src/test/ui/unsized/unchanged-param.rs b/src/test/ui/unsized/unchanged-param.rs new file mode 100644 index 0000000000000..93c7af68ac388 --- /dev/null +++ b/src/test/ui/unsized/unchanged-param.rs @@ -0,0 +1,11 @@ +// run-pass +// Test that we allow unsizing even if there is an unchanged param in the +// field getting unsized. +struct A(T, B); +struct B(T, U); + +fn main() { + let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1])); + let y: &A<[u32; 1], [u32]> = &x; + assert_eq!(y.1.1.len(), 1); +} From 031cce8cfc7fef922989e8b820da236ee17e016a Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 3 Feb 2021 23:56:47 +0100 Subject: [PATCH 14/26] add `relaxed_struct_unsize` feature gate --- compiler/rustc_feature/src/active.rs | 3 + compiler/rustc_span/src/symbol.rs | 1 + .../src/traits/select/confirmation.rs | 59 ++++++++++++++----- .../feature-gate-relaxed_struct_unsize.rs | 10 ++++ .../feature-gate-relaxed_struct_unsize.stderr | 14 +++++ src/test/ui/unsized/unchanged-param.rs | 1 + 6 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.rs create mode 100644 src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 818f6c70de01e..4f38e06002367 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -631,6 +631,9 @@ declare_features! ( /// Allows `extern "C-cmse-nonsecure-call" fn()`. (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None), + + /// Lessens the requirements for structs to implement `Unsize`. + (active, relaxed_struct_unsize, "1.51.0", Some(1), None), // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index df23b4006b347..86f8061a24aff 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -907,6 +907,7 @@ symbols! { register_attr, register_tool, relaxed_adts, + relaxed_struct_unsize, rem, rem_assign, repr, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3e3e945f654b7..ed3e117fcfabb 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -823,33 +823,62 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }, }; + // FIXME(eddyb) cache this (including computing `unsizing_params`) + // by putting it in a query; it would only need the `DefId` as it + // looks at declared field types, not anything substituted. + // The last field of the structure has to exist and contain type/const parameters. let (tail_field, prefix_fields) = def.non_enum_variant().fields.split_last().ok_or(Unimplemented)?; let tail_field_ty = tcx.type_of(tail_field.did); let mut unsizing_params = GrowableBitSet::new_empty(); - for arg in tail_field_ty.walk() { - if let Some(i) = maybe_unsizing_param_idx(arg) { - unsizing_params.insert(i); + if tcx.features().relaxed_struct_unsize { + for arg in tail_field_ty.walk() { + if let Some(i) = maybe_unsizing_param_idx(arg) { + unsizing_params.insert(i); + } } - } - // Ensure none of the other fields mention the parameters used - // in unsizing. - // FIXME(eddyb) cache this (including computing `unsizing_params`) - // by putting it in a query; it would only need the `DefId` as it - // looks at declared field types, not anything substituted. - for field in prefix_fields { - for arg in tcx.type_of(field.did).walk() { + // Ensure none of the other fields mention the parameters used + // in unsizing. + for field in prefix_fields { + for arg in tcx.type_of(field.did).walk() { + if let Some(i) = maybe_unsizing_param_idx(arg) { + unsizing_params.remove(i); + } + } + } + + if unsizing_params.is_empty() { + return Err(Unimplemented); + } + } else { + let mut found = false; + for arg in tail_field_ty.walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { - unsizing_params.remove(i); + unsizing_params.insert(i); + found = true; } } - } + if !found { + return Err(Unimplemented); + } - if unsizing_params.is_empty() { - return Err(Unimplemented); + // Ensure none of the other fields mention the parameters used + // in unsizing. + // FIXME(eddyb) cache this (including computing `unsizing_params`) + // by putting it in a query; it would only need the `DefId` as it + // looks at declared field types, not anything substituted. + for field in prefix_fields { + for arg in tcx.type_of(field.did).walk() { + if let Some(i) = maybe_unsizing_param_idx(arg) { + if unsizing_params.contains(i) { + return Err(Unimplemented); + } + } + } + } } // Extract `TailField` and `TailField` from `Struct` and `Struct`. diff --git a/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.rs b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.rs new file mode 100644 index 0000000000000..0cfd0a0b9784c --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.rs @@ -0,0 +1,10 @@ +// Test that we allow unsizing even if there is an unchanged param in the +// field getting unsized. +struct A(T, B); +struct B(T, U); + +fn main() { + let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1])); + let y: &A<[u32; 1], [u32]> = &x; //~ ERROR mismatched types + assert_eq!(y.1.1.len(), 1); +} diff --git a/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr new file mode 100644 index 0000000000000..f62def47726f9 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/feature-gate-relaxed_struct_unsize.rs:8:34 + | +LL | let y: &A<[u32; 1], [u32]> = &x; + | ------------------- ^^ expected slice `[u32]`, found array `[u32; 1]` + | | + | expected due to this + | + = note: expected reference `&A<[u32; 1], [u32]>` + found reference `&A<[u32; 1], [u32; 1]>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/unsized/unchanged-param.rs b/src/test/ui/unsized/unchanged-param.rs index 93c7af68ac388..83199e8112e71 100644 --- a/src/test/ui/unsized/unchanged-param.rs +++ b/src/test/ui/unsized/unchanged-param.rs @@ -1,3 +1,4 @@ +#![feature(relaxed_struct_unsize)] // run-pass // Test that we allow unsizing even if there is an unchanged param in the // field getting unsized. From d06384ac29098c3a4b3e21eb2f70093e800bd1b6 Mon Sep 17 00:00:00 2001 From: RustyYato Date: Wed, 3 Feb 2021 16:59:28 -0500 Subject: [PATCH 15/26] make Allocator object-safe add test to ensure object-safety This allows for runtime polymorphic allocators --- library/core/src/alloc/mod.rs | 5 ++++- src/test/ui/allocator/object-safe.rs | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/allocator/object-safe.rs diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 045eb58d0135a..9c2a0146e2c3d 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -342,7 +342,10 @@ pub unsafe trait Allocator { /// /// The returned adaptor also implements `Allocator` and will simply borrow this. #[inline(always)] - fn by_ref(&self) -> &Self { + fn by_ref(&self) -> &Self + where + Self: Sized, + { self } } diff --git a/src/test/ui/allocator/object-safe.rs b/src/test/ui/allocator/object-safe.rs new file mode 100644 index 0000000000000..fae7ab7fe3319 --- /dev/null +++ b/src/test/ui/allocator/object-safe.rs @@ -0,0 +1,13 @@ +// run-pass + +// Check that `Allocator` is object safe, this allows for polymorphic allocators + +#![feature(allocator_api)] + +use std::alloc::{Allocator, System}; + +fn ensure_object_safe(_: &dyn Allocator) {} + +fn main() { + ensure_object_safe(&System); +} From fdaf603102943392e889ea203adb8fa8f4a8d7a7 Mon Sep 17 00:00:00 2001 From: b-naber Date: Mon, 30 Nov 2020 09:23:00 +0100 Subject: [PATCH 16/26] add generic args to hir::TypeBinding --- compiler/rustc_hir/src/hir.rs | 1 + compiler/rustc_hir/src/intravisit.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 1c16dc026670b..a0b2e0a8861e0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2015,6 +2015,7 @@ pub struct TypeBinding<'hir> { pub hir_id: HirId, #[stable_hasher(project(name))] pub ident: Ident, + pub gen_args: &'hir GenericArgs<'hir>, pub kind: TypeBindingKind<'hir>, pub span: Span, } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 6c1bee2335a00..f8b3f0d9b6e23 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -781,6 +781,7 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>( ) { visitor.visit_id(type_binding.hir_id); visitor.visit_ident(type_binding.ident); + visitor.visit_generic_args(type_binding.span, type_binding.gen_args); match type_binding.kind { TypeBindingKind::Equality { ref ty } => { visitor.visit_ty(ty); From 16af7bf3d9a3d86f6315bd86200d71de85e18a2d Mon Sep 17 00:00:00 2001 From: b-naber Date: Mon, 30 Nov 2020 09:23:59 +0100 Subject: [PATCH 17/26] hir pretty printing --- compiler/rustc_hir_pretty/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index f1c2a6b7e6e85..4595855309fda 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1840,6 +1840,7 @@ impl<'a> State<'a> { for binding in generic_args.bindings.iter() { start_or_comma(self); self.print_ident(binding.ident); + self.print_generic_args(binding.gen_args, false, false); self.s.space(); match generic_args.bindings[0].kind { hir::TypeBindingKind::Equality { ref ty } => { From 760a6654fbddea5d7a9beefe100f0fb784e96928 Mon Sep 17 00:00:00 2001 From: b-naber Date: Mon, 30 Nov 2020 09:24:54 +0100 Subject: [PATCH 18/26] lowering of generic args in AssocTyConstraint --- compiler/rustc_ast_lowering/src/lib.rs | 39 ++++++++++++++++++++----- compiler/rustc_ast_lowering/src/path.rs | 7 +++-- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b7f227da73e31..f076dca5cf5f1 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1076,16 +1076,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_assoc_ty_constraint( &mut self, constraint: &AssocTyConstraint, - itctx: ImplTraitContext<'_, 'hir>, + mut itctx: ImplTraitContext<'_, 'hir>, ) -> hir::TypeBinding<'hir> { debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); - if let Some(ref gen_args) = constraint.gen_args { - self.sess.span_fatal( - gen_args.span(), - "generic associated types in trait paths are currently not implemented", - ); - } + // lower generic arguments of identifier in constraint + let gen_args = if let Some(ref gen_args) = constraint.gen_args { + let gen_args_ctor = match gen_args { + GenericArgs::AngleBracketed(ref data) => { + self.lower_angle_bracketed_parameter_data( + data, + ParamMode::Explicit, + itctx.reborrow(), + ) + .0 + } + GenericArgs::Parenthesized(ref data) => { + let mut err = self.sess.struct_span_err( + gen_args.span(), + "parenthesized generic arguments cannot be used in associated type constraints" + ); + // FIXME: try to write a suggestion here + err.emit(); + self.lower_angle_bracketed_parameter_data( + &data.as_angle_bracketed_args(), + ParamMode::Explicit, + itctx.reborrow(), + ) + .0 + } + }; + self.arena.alloc(gen_args_ctor.into_generic_args(&self.arena)) + } else { + self.arena.alloc(hir::GenericArgs::none()) + }; let kind = match constraint.kind { AssocTyConstraintKind::Equality { ref ty } => { @@ -1182,6 +1206,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBinding { hir_id: self.lower_node_id(constraint.id), ident: constraint.ident, + gen_args, kind, span: constraint.span, } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 9079e26eb509e..cb4d5ea6ee650 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -362,7 +362,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_angle_bracketed_parameter_data( + pub(crate) fn lower_angle_bracketed_parameter_data( &mut self, data: &AngleBracketedArgs, param_mode: ParamMode, @@ -426,6 +426,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::TypeBinding<'hir> { let ident = Ident::with_dummy_span(hir::FN_OUTPUT_NAME); let kind = hir::TypeBindingKind::Equality { ty }; - hir::TypeBinding { hir_id: self.next_id(), span, ident, kind } + let args = arena_vec![self;]; + let bindings = arena_vec![self;]; + let gen_args = self.arena.alloc(hir::GenericArgs { args, bindings, parenthesized: false }); + hir::TypeBinding { hir_id: self.next_id(), gen_args, span, ident, kind } } } From da2cf9b9d152ab21df7194563ac2aa871ce6d9c5 Mon Sep 17 00:00:00 2001 From: b-naber Date: Mon, 30 Nov 2020 09:26:22 +0100 Subject: [PATCH 19/26] substitutions in trait predicates --- compiler/rustc_typeck/src/astconv/mod.rs | 166 ++++++++++++++--------- 1 file changed, 104 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 437813ea41bd5..5659345f0ff9c 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -112,12 +112,15 @@ pub enum SizedByDefault { No, } +#[derive(Debug)] struct ConvertedBinding<'a, 'tcx> { item_name: Ident, kind: ConvertedBindingKind<'a, 'tcx>, + gen_args: &'a GenericArgs<'a>, span: Span, } +#[derive(Debug)] enum ConvertedBindingKind<'a, 'tcx> { Equality(Ty<'tcx>), Constraint(&'a [hir::GenericBound<'a>]), @@ -323,6 +326,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); let generics = tcx.generics_of(def_id); + debug!("generics: {:?}", generics); if generics.has_self { if generics.parent.is_some() { @@ -557,7 +561,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ConvertedBindingKind::Constraint(bounds) } }; - ConvertedBinding { item_name: binding.ident, kind, span: binding.span } + ConvertedBinding { + item_name: binding.ident, + kind, + gen_args: binding.gen_args, + span: binding.span, + } }) .collect(); @@ -918,60 +927,27 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { dup_bindings: &mut FxHashMap, path_span: Span, ) -> Result<(), ErrorReported> { - let tcx = self.tcx(); - - if !speculative { - // Given something like `U: SomeTrait`, we want to produce a - // predicate like `::T = X`. This is somewhat - // subtle in the event that `T` is defined in a supertrait of - // `SomeTrait`, because in that case we need to upcast. - // - // That is, consider this case: - // - // ``` - // trait SubTrait: SuperTrait { } - // trait SuperTrait { type T; } - // - // ... B: SubTrait ... - // ``` - // - // We want to produce `>::T == foo`. - - // Find any late-bound regions declared in `ty` that are not - // declared in the trait-ref. These are not well-formed. - // - // Example: - // - // for<'a> ::Item = &'a str // <-- 'a is bad - // for<'a> >::Output = &'a str // <-- 'a is ok - if let ConvertedBindingKind::Equality(ty) = binding.kind { - let late_bound_in_trait_ref = - tcx.collect_constrained_late_bound_regions(&trait_ref); - let late_bound_in_ty = - tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty)); - debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref); - debug!("late_bound_in_ty = {:?}", late_bound_in_ty); + // Given something like `U: SomeTrait`, we want to produce a + // predicate like `::T = X`. This is somewhat + // subtle in the event that `T` is defined in a supertrait of + // `SomeTrait`, because in that case we need to upcast. + // + // That is, consider this case: + // + // ``` + // trait SubTrait: SuperTrait { } + // trait SuperTrait { type T; } + // + // ... B: SubTrait ... + // ``` + // + // We want to produce `>::T == foo`. - // FIXME: point at the type params that don't have appropriate lifetimes: - // struct S1 Fn(&i32, &i32) -> &'a i32>(F); - // ---- ---- ^^^^^^^ - self.validate_late_bound_regions( - late_bound_in_trait_ref, - late_bound_in_ty, - |br_name| { - struct_span_err!( - tcx.sess, - binding.span, - E0582, - "binding for associated type `{}` references {}, \ - which does not appear in the trait input types", - binding.item_name, - br_name - ) - }, - ); - } - } + debug!( + "add_predicates_for_ast_type_binding(hir_ref_id {:?}, trait_ref {:?}, binding {:?}, bounds {:?}", + hir_ref_id, trait_ref, binding, bounds + ); + let tcx = self.tcx(); let candidate = if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) { @@ -1030,6 +1006,72 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .or_insert(binding.span); } + // Include substitutions for generic parameters of associated types + let projection_ty = candidate.map_bound(|trait_ref| { + let item_segment = hir::PathSegment { + ident: assoc_ty.ident, + hir_id: None, + res: None, + args: Some(binding.gen_args), + infer_args: false, + }; + + let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item( + tcx, + path_span, + assoc_ty.def_id, + &item_segment, + trait_ref.substs, + ); + + debug!( + "add_predicates_for_ast_type_binding: substs for trait-ref and assoc_item: {:?}", + substs_trait_ref_and_assoc_item + ); + + ty::ProjectionTy { + item_def_id: assoc_ty.def_id, + substs: substs_trait_ref_and_assoc_item, + } + }); + + if !speculative { + // Find any late-bound regions declared in `ty` that are not + // declared in the trait-ref or assoc_ty. These are not well-formed. + // + // Example: + // + // for<'a> ::Item = &'a str // <-- 'a is bad + // for<'a> >::Output = &'a str // <-- 'a is ok + if let ConvertedBindingKind::Equality(ty) = binding.kind { + let late_bound_in_trait_ref = + tcx.collect_constrained_late_bound_regions(&projection_ty); + let late_bound_in_ty = + tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty)); + debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref); + debug!("late_bound_in_ty = {:?}", late_bound_in_ty); + + // FIXME: point at the type params that don't have appropriate lifetimes: + // struct S1 Fn(&i32, &i32) -> &'a i32>(F); + // ---- ---- ^^^^^^^ + self.validate_late_bound_regions( + late_bound_in_trait_ref, + late_bound_in_ty, + |br_name| { + struct_span_err!( + tcx.sess, + binding.span, + E0582, + "binding for associated type `{}` references {}, \ + which does not appear in the trait input types", + binding.item_name, + br_name + ) + }, + ); + } + } + match binding.kind { ConvertedBindingKind::Equality(ref ty) => { // "Desugar" a constraint like `T: Iterator` this to @@ -1037,13 +1079,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // // `::Item = u32` bounds.projection_bounds.push(( - candidate.map_bound(|trait_ref| ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy::from_ref_and_name( - tcx, - trait_ref, - binding.item_name, - ), - ty, + projection_ty.map_bound(|projection_ty| { + debug!( + "add_predicates_for_ast_type_binding: projection_ty {:?}, substs: {:?}", + projection_ty, projection_ty.substs + ); + ty::ProjectionPredicate { projection_ty, ty } }), binding.span, )); @@ -1055,7 +1096,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty` // parameter to have a skipped binder. - let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs); + let param_ty = + tcx.mk_projection(assoc_ty.def_id, projection_ty.skip_binder().substs); self.add_bounds(param_ty, ast_bounds, bounds); } } From 6a68966663b8412d8f863e5c9dd161085d24d128 Mon Sep 17 00:00:00 2001 From: b-naber Date: Mon, 30 Nov 2020 09:27:23 +0100 Subject: [PATCH 20/26] use generic arguments of associated item in trait_ref method --- compiler/rustc_middle/src/ty/sty.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 6b4f08d9f9335..c1fa84dcb25e0 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1132,8 +1132,16 @@ impl<'tcx> ProjectionTy<'tcx> { /// For example, if this is a projection of `::Item`, /// then this function would return a `T: Iterator` trait reference. pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { + // FIXME: This method probably shouldn't exist at all, since it's not + // clear what this method really intends to do. Be careful when + // using this method since the resulting TraitRef additionally + // contains the substs for the assoc_item, which strictly speaking + // is not correct let def_id = tcx.associated_item(self.item_def_id).container.id(); - ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)) } + // Include substitutions for generic arguments of associated types + let assoc_item = tcx.associated_item(self.item_def_id); + let substs_assoc_item = self.substs.truncate_to(tcx, tcx.generics_of(assoc_item.def_id)); + ty::TraitRef { def_id, substs: substs_assoc_item } } pub fn self_ty(&self) -> Ty<'tcx> { From 9e920151a32bf2c33fc83dacbbc845aa3956f582 Mon Sep 17 00:00:00 2001 From: b-naber Date: Mon, 30 Nov 2020 09:28:16 +0100 Subject: [PATCH 21/26] remove subst_supertrait call --- compiler/rustc_trait_selection/src/traits/object_safety.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 3852005ee3f35..e155f0366e19f 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -257,13 +257,11 @@ fn predicates_reference_self( } fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> { - let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); tcx.associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) .flat_map(|item| tcx.explicit_item_bounds(item.def_id)) - .map(|&(predicate, sp)| (predicate.subst_supertrait(tcx, &trait_ref), sp)) - .filter_map(|predicate| predicate_references_self(tcx, predicate)) + .filter_map(|pred_span| predicate_references_self(tcx, *pred_span)) .collect() } From b080d1c67021c42361e35a949bdc52af1b2b7fc4 Mon Sep 17 00:00:00 2001 From: Camelid Date: Thu, 4 Feb 2021 13:19:01 -0800 Subject: [PATCH 22/26] Cleanup rustdoc pass descriptions a bit Also changed a couple of comments from "intra-doc-links" to "intra-doc links" (my understanding is that "intra-doc links" is the standard way to refer to them). --- src/librustdoc/core.rs | 2 +- src/librustdoc/passes/collect_intra_doc_links.rs | 4 ++-- src/librustdoc/passes/doc_test_lints.rs | 4 ++-- src/librustdoc/passes/non_autolinks.rs | 2 +- src/librustdoc/passes/strip_hidden.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index aa18684aea197..a20e9dec33b36 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -435,7 +435,7 @@ crate fn create_resolver<'a>( // Before we actually clone it, let's force all the extern'd crates to // actually be loaded, just in case they're only referred to inside - // intra-doc-links + // intra-doc links resolver.borrow_mut().access(|resolver| { sess.time("load_extern_crates", || { for extern_name in &extern_names { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 002d8938f694d..532a0cf932904 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -44,7 +44,7 @@ use super::span_of_attrs; crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass { name: "collect-intra-doc-links", run: collect_intra_doc_links, - description: "reads a crate's documentation to resolve intra-doc-links", + description: "resolves intra-doc links", }; crate fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate { @@ -981,7 +981,7 @@ impl LinkCollector<'_, '_> { let link_text = disambiguator.map(|d| d.display_for(path_str)).unwrap_or_else(|| path_str.to_owned()); - // In order to correctly resolve intra-doc-links we need to + // In order to correctly resolve intra-doc links we need to // pick a base AST node to work from. If the documentation for // this module came from an inner comment (//!) then we anchor // our name resolution *inside* the module. If, on the other diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index a513c2abc8747..11f572560d606 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -1,7 +1,7 @@ //! This pass is overloaded and runs two different lints. //! -//! - MISSING_DOC_CODE_EXAMPLES: this lint is **UNSTABLE** and looks for public items missing doc-tests -//! - PRIVATE_DOC_TESTS: this lint is **STABLE** and looks for private items with doc-tests. +//! - MISSING_DOC_CODE_EXAMPLES: this lint is **UNSTABLE** and looks for public items missing doctests +//! - PRIVATE_DOC_TESTS: this lint is **STABLE** and looks for private items with doctests. use super::{span_of_attrs, Pass}; use crate::clean; diff --git a/src/librustdoc/passes/non_autolinks.rs b/src/librustdoc/passes/non_autolinks.rs index 1f411b997f802..efb5df08cafdb 100644 --- a/src/librustdoc/passes/non_autolinks.rs +++ b/src/librustdoc/passes/non_autolinks.rs @@ -12,7 +12,7 @@ use rustc_session::lint; crate const CHECK_NON_AUTOLINKS: Pass = Pass { name: "check-non-autolinks", run: check_non_autolinks, - description: "detects URLS that could be written using angle brackets", + description: "detects URLs that could be linkified", }; const URL_REGEX: &str = concat!( diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index a276b7a63371b..79f8562c4726d 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -11,7 +11,7 @@ use crate::passes::{ImplStripper, Pass}; crate const STRIP_HIDDEN: Pass = Pass { name: "strip-hidden", run: strip_hidden, - description: "strips all doc(hidden) items from the output", + description: "strips all `#[doc(hidden)]` items from the output", }; /// Strip items marked `#[doc(hidden)]` From 12d411febb37d4ddfd423415554714265609cb72 Mon Sep 17 00:00:00 2001 From: b-naber Date: Mon, 30 Nov 2020 09:30:14 +0100 Subject: [PATCH 23/26] add tests --- .../gat-in-trait-path-undeclared-lifetime.rs | 12 ++++ ...t-in-trait-path-undeclared-lifetime.stderr | 29 ++++++++ .../gat-in-trait-path.rs | 30 ++++++++ .../gat-in-trait-path.stderr | 11 +++ .../gat-trait-path-generic-type-arg.rs | 16 +++++ .../gat-trait-path-generic-type-arg.stderr | 32 +++++++++ .../gat-trait-path-missing-lifetime.rs | 18 +++++ .../gat-trait-path-missing-lifetime.stderr | 44 ++++++++++++ .../gat-trait-path-parenthesised-args.rs | 15 ++++ .../gat-trait-path-parenthesised-args.stderr | 68 +++++++++++++++++++ .../issue-67510-pass.rs | 12 ++++ .../issue-67510-pass.stderr | 11 +++ .../generic-associated-types/issue-67510.rs | 13 ++++ .../issue-67510.stderr | 32 +++++++++ .../generic-associated-types/issue-68648-1.rs | 26 +++++++ .../issue-68648-1.stderr | 11 +++ .../generic-associated-types/issue-68648-2.rs | 24 +++++++ .../issue-68648-2.stderr | 23 +++++++ .../issue-68649-pass.rs | 25 +++++++ .../issue-68649-pass.stderr | 11 +++ .../generic-associated-types/issue-74684-1.rs | 26 +++++++ .../issue-74684-1.stderr | 27 ++++++++ .../generic-associated-types/issue-74684-2.rs | 26 +++++++ .../issue-74684-2.stderr | 21 ++++++ .../generic-associated-types/issue-76535.rs | 41 +++++++++++ .../issue-76535.stderr | 63 +++++++++++++++++ .../generic-associated-types/issue-79422.rs | 47 +++++++++++++ .../issue-79422.stderr | 54 +++++++++++++++ .../issue-80433-reduced.rs | 24 +++++++ .../generic-associated-types/issue-80433.rs | 35 ++++++++++ .../issue-80433.stderr | 19 ++++++ .../trait-path-type-error-once-implemented.rs | 6 +- ...it-path-type-error-once-implemented.stderr | 51 ++++++++++++-- .../parse/trait-path-unimplemented.rs | 17 ----- .../parse/trait-path-unimplemented.stderr | 14 ---- 35 files changed, 897 insertions(+), 37 deletions(-) create mode 100644 src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs create mode 100644 src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr create mode 100644 src/test/ui/generic-associated-types/gat-in-trait-path.rs create mode 100644 src/test/ui/generic-associated-types/gat-in-trait-path.stderr create mode 100644 src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs create mode 100644 src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr create mode 100644 src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs create mode 100644 src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr create mode 100644 src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs create mode 100644 src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr create mode 100644 src/test/ui/generic-associated-types/issue-67510-pass.rs create mode 100644 src/test/ui/generic-associated-types/issue-67510-pass.stderr create mode 100644 src/test/ui/generic-associated-types/issue-67510.rs create mode 100644 src/test/ui/generic-associated-types/issue-67510.stderr create mode 100644 src/test/ui/generic-associated-types/issue-68648-1.rs create mode 100644 src/test/ui/generic-associated-types/issue-68648-1.stderr create mode 100644 src/test/ui/generic-associated-types/issue-68648-2.rs create mode 100644 src/test/ui/generic-associated-types/issue-68648-2.stderr create mode 100644 src/test/ui/generic-associated-types/issue-68649-pass.rs create mode 100644 src/test/ui/generic-associated-types/issue-68649-pass.stderr create mode 100644 src/test/ui/generic-associated-types/issue-74684-1.rs create mode 100644 src/test/ui/generic-associated-types/issue-74684-1.stderr create mode 100644 src/test/ui/generic-associated-types/issue-74684-2.rs create mode 100644 src/test/ui/generic-associated-types/issue-74684-2.stderr create mode 100644 src/test/ui/generic-associated-types/issue-76535.rs create mode 100644 src/test/ui/generic-associated-types/issue-76535.stderr create mode 100644 src/test/ui/generic-associated-types/issue-79422.rs create mode 100644 src/test/ui/generic-associated-types/issue-79422.stderr create mode 100644 src/test/ui/generic-associated-types/issue-80433-reduced.rs create mode 100644 src/test/ui/generic-associated-types/issue-80433.rs create mode 100644 src/test/ui/generic-associated-types/issue-80433.stderr delete mode 100644 src/test/ui/generic-associated-types/parse/trait-path-unimplemented.rs delete mode 100644 src/test/ui/generic-associated-types/parse/trait-path-unimplemented.stderr diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs new file mode 100644 index 0000000000000..2c543455b6ebd --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs @@ -0,0 +1,12 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'x>; +} + +fn main() { + fn _f(arg : Box X = &'a [u32]>>) {} + //~^ ERROR: use of undeclared lifetime name `'x` + //~| ERROR: binding for associated type `Y` references lifetime +} diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr new file mode 100644 index 0000000000000..1c7c107d78354 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr @@ -0,0 +1,29 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0261]: use of undeclared lifetime name `'x` + --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:9:35 + | +LL | fn _f(arg : Box X = &'a [u32]>>) {} + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'x` here: `<'x>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes + +error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types + --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:9:33 + | +LL | fn _f(arg : Box X = &'a [u32]>>) {} + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0261, E0582. +For more information about an error, try `rustc --explain E0261`. diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.rs b/src/test/ui/generic-associated-types/gat-in-trait-path.rs new file mode 100644 index 0000000000000..2dbd1840dec55 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-in-trait-path.rs @@ -0,0 +1,30 @@ +// check-pass + +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete +#![feature(associated_type_defaults)] + +trait Foo { + type A<'a> where Self: 'a; +} + +struct Fooy; + +impl Foo for Fooy { + type A<'a> = &'a (); +} + +#[derive(Clone)] +struct Fooer(T); + +impl Foo for Fooer { + type A<'x> where T: 'x = &'x (); +} + +fn f(_arg : Box Foo = &'a ()>>) {} + + +fn main() { + let foo = Fooer(5); + f(Box::new(foo)); +} diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr new file mode 100644 index 0000000000000..f3769827f04b2 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-in-trait-path.rs:3:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs new file mode 100644 index 0000000000000..cff5a21052f9b --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs @@ -0,0 +1,16 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Foo { + type F<'a>; + + fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t } +} + +impl Foo for T { + type F = &[u8]; + //~^ ERROR: the name `T1` is already used for + //~| ERROR: missing lifetime specifier +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr new file mode 100644 index 0000000000000..e83af1d0c739d --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr @@ -0,0 +1,32 @@ +error[E0403]: the name `T1` is already used for a generic parameter in this item's generic parameters + --> $DIR/gat-trait-path-generic-type-arg.rs:11:12 + | +LL | impl Foo for T { + | -- first use of `T1` +LL | type F = &[u8]; + | ^^ already used + +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-trait-path-generic-type-arg.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0106]: missing lifetime specifier + --> $DIR/gat-trait-path-generic-type-arg.rs:11:18 + | +LL | type F = &[u8]; + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | type F<'a, T1> = &'a [u8]; + | ^^^ ^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0106, E0403. +For more information about an error, try `rustc --explain E0106`. diff --git a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs new file mode 100644 index 0000000000000..e69e355ba48e5 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs @@ -0,0 +1,18 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'a>; + //~^ ERROR missing generics for + //~| ERROR missing generics for + + fn foo<'a>(t : Self::Y<'a>) -> Self::Y<'a> { t } +} + +impl X for T { + fn foo<'a, T1: X>(t : T1) -> T1::Y<'a> { + t + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr new file mode 100644 index 0000000000000..9c6e2ce3e17a3 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr @@ -0,0 +1,44 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-trait-path-missing-lifetime.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0107]: missing generics for associated type `X::Y` + --> $DIR/gat-trait-path-missing-lifetime.rs:5:8 + | +LL | type Y<'a>; + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/gat-trait-path-missing-lifetime.rs:5:8 + | +LL | type Y<'a>; + | ^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type Y<'a><'a>; + | ^^^^ + +error[E0107]: missing generics for associated type `X::Y` + --> $DIR/gat-trait-path-missing-lifetime.rs:5:8 + | +LL | type Y<'a>; + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/gat-trait-path-missing-lifetime.rs:5:8 + | +LL | type Y<'a>; + | ^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type Y<'a><'a>; + | ^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs new file mode 100644 index 0000000000000..bb1f27a17ca4c --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs @@ -0,0 +1,15 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'a>; + //~^ ERROR this associated type + //~| ERROR this associated type +} + +fn foo<'a>(arg: Box>) {} + //~^ ERROR: lifetime in trait object type must be followed by `+` + //~| ERROR: parenthesized generic arguments cannot be used + //~| WARNING: trait objects without an explicit `dyn` are deprecated + +fn main() {} diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr new file mode 100644 index 0000000000000..20cb6d8828755 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -0,0 +1,68 @@ +error: lifetime in trait object type must be followed by `+` + --> $DIR/gat-trait-path-parenthesised-args.rs:10:29 + | +LL | fn foo<'a>(arg: Box>) {} + | ^^ + +error: parenthesized generic arguments cannot be used in associated type constraints + --> $DIR/gat-trait-path-parenthesised-args.rs:10:27 + | +LL | fn foo<'a>(arg: Box>) {} + | ^^^^^ + +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-trait-path-parenthesised-args.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/gat-trait-path-parenthesised-args.rs:10:29 + | +LL | fn foo<'a>(arg: Box>) {} + | ^^ help: use `dyn`: `dyn 'a` + | + = note: `#[warn(bare_trait_objects)]` on by default + +error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/gat-trait-path-parenthesised-args.rs:5:8 + | +LL | type Y<'a>; + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/gat-trait-path-parenthesised-args.rs:5:8 + | +LL | type Y<'a>; + | ^ -- +help: add missing lifetime argument + | +LL | fn foo<'a>(arg: Box>) {} + | ^^ + +error[E0107]: this associated type takes 0 type arguments but 1 type argument was supplied + --> $DIR/gat-trait-path-parenthesised-args.rs:5:8 + | +LL | type Y<'a>; + | ________^- + | | | + | | expected 0 type arguments +LL | | +LL | | +LL | | } +LL | | +LL | | fn foo<'a>(arg: Box>) {} + | |_________________________________________- help: remove these generics + | +note: associated type defined here, with 0 type parameters + --> $DIR/gat-trait-path-parenthesised-args.rs:5:8 + | +LL | type Y<'a>; + | ^ + +error: aborting due to 4 previous errors; 2 warnings emitted + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.rs b/src/test/ui/generic-associated-types/issue-67510-pass.rs new file mode 100644 index 0000000000000..ff38b3e93eb1a --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-67510-pass.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'a>; +} + +fn _func1<'a>(_x: Box=&'a ()>>) {} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.stderr b/src/test/ui/generic-associated-types/issue-67510-pass.stderr new file mode 100644 index 0000000000000..0fbf704df76a1 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-67510-pass.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-67510-pass.rs:3:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/generic-associated-types/issue-67510.rs b/src/test/ui/generic-associated-types/issue-67510.rs new file mode 100644 index 0000000000000..62b22089f917c --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-67510.rs @@ -0,0 +1,13 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'a>; +} + +fn f(x: Box=&'a ()>>) {} + //~^ ERROR: use of undeclared lifetime name `'a` + //~| ERROR: use of undeclared lifetime name `'a` + + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-67510.stderr b/src/test/ui/generic-associated-types/issue-67510.stderr new file mode 100644 index 0000000000000..12755c56974f2 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-67510.stderr @@ -0,0 +1,32 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-67510.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/issue-67510.rs:8:21 + | +LL | fn f(x: Box=&'a ()>>) {} + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/issue-67510.rs:8:26 + | +LL | fn f(x: Box=&'a ()>>) {} + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/generic-associated-types/issue-68648-1.rs b/src/test/ui/generic-associated-types/issue-68648-1.rs new file mode 100644 index 0000000000000..f294b22f73c67 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68648-1.rs @@ -0,0 +1,26 @@ +// check-pass + +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + + +trait Fun { + type F<'a>; + + fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = Self; +} + +fn bug<'a, T: for<'b> Fun = T>>(t: T) -> T::F<'a> { + T::identity(t) +} + + +fn main() { + let x = 10; + + bug(x); +} diff --git a/src/test/ui/generic-associated-types/issue-68648-1.stderr b/src/test/ui/generic-associated-types/issue-68648-1.stderr new file mode 100644 index 0000000000000..322a8f9e13f81 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68648-1.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-68648-1.rs:3:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/generic-associated-types/issue-68648-2.rs b/src/test/ui/generic-associated-types/issue-68648-2.rs new file mode 100644 index 0000000000000..e55bfcd4ba295 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68648-2.rs @@ -0,0 +1,24 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Fun { + type F<'a>; + + fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = Self; +} + +fn bug<'a, T: Fun = T>>(t: T) -> T::F<'a> { + T::identity(()) + //~^ ERROR: mismatched types +} + + +fn main() { + let x = 10; + + bug(x); +} diff --git a/src/test/ui/generic-associated-types/issue-68648-2.stderr b/src/test/ui/generic-associated-types/issue-68648-2.stderr new file mode 100644 index 0000000000000..b51e0bca9f7a9 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68648-2.stderr @@ -0,0 +1,23 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-68648-2.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0308]: mismatched types + --> $DIR/issue-68648-2.rs:15:17 + | +LL | fn bug<'a, T: Fun = T>>(t: T) -> T::F<'a> { + | - this type parameter +LL | T::identity(()) + | ^^ expected type parameter `T`, found `()` + | + = note: expected type parameter `T` + found unit type `()` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/generic-associated-types/issue-68649-pass.rs b/src/test/ui/generic-associated-types/issue-68649-pass.rs new file mode 100644 index 0000000000000..396315302f74c --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68649-pass.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Fun { + type F<'a>; + + fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = Self; +} + +fn bug<'a, T: Fun = T>>(t: T) -> T::F<'a> { + T::identity(t) +} + + +fn main() { + let x = 10; + + bug(x); +} diff --git a/src/test/ui/generic-associated-types/issue-68649-pass.stderr b/src/test/ui/generic-associated-types/issue-68649-pass.stderr new file mode 100644 index 0000000000000..e4a2f8d2a6401 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68649-pass.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-68649-pass.rs:3:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/generic-associated-types/issue-74684-1.rs b/src/test/ui/generic-associated-types/issue-74684-1.rs new file mode 100644 index 0000000000000..a483da863ff00 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-74684-1.rs @@ -0,0 +1,26 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Fun { + type F<'a>: ?Sized; + + fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = [u8]; +} + +fn bug<'a, T: ?Sized + Fun = [u8]>>(_ : Box) -> &'static T::F<'a> { + let a = [0; 1]; + let _x = T::identity(&a); + //~^ ERROR: `a` does not live long enough + todo!() +} + + +fn main() { + let x = 10; + + bug(Box::new(x)); +} diff --git a/src/test/ui/generic-associated-types/issue-74684-1.stderr b/src/test/ui/generic-associated-types/issue-74684-1.stderr new file mode 100644 index 0000000000000..651da696827c3 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-74684-1.stderr @@ -0,0 +1,27 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-74684-1.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0597]: `a` does not live long enough + --> $DIR/issue-74684-1.rs:16:26 + | +LL | fn bug<'a, T: ?Sized + Fun = [u8]>>(_ : Box) -> &'static T::F<'a> { + | -- lifetime `'a` defined here +LL | let a = [0; 1]; +LL | let _x = T::identity(&a); + | ------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `a` is borrowed for `'a` +... +LL | } + | - `a` dropped here while still borrowed + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/generic-associated-types/issue-74684-2.rs b/src/test/ui/generic-associated-types/issue-74684-2.rs new file mode 100644 index 0000000000000..0caf19cb03038 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-74684-2.rs @@ -0,0 +1,26 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Fun { + type F<'a>: ?Sized; + + fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = i32; +} + +fn bug<'a, T: ?Sized + Fun = [u8]>>(t: Box) -> &'static T::F<'a> { + let a = [0; 1]; + let x = T::identity(&a); + todo!() +} + + +fn main() { + let x = 10; + + bug(Box::new(x)); + //~^ ERROR: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]` +} diff --git a/src/test/ui/generic-associated-types/issue-74684-2.stderr b/src/test/ui/generic-associated-types/issue-74684-2.stderr new file mode 100644 index 0000000000000..8c3484f9a7300 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-74684-2.stderr @@ -0,0 +1,21 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-74684-2.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0271]: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]` + --> $DIR/issue-74684-2.rs:24:5 + | +LL | fn bug<'a, T: ?Sized + Fun = [u8]>>(t: Box) -> &'static T::F<'a> { + | ------------ required by this bound in `bug` +... +LL | bug(Box::new(x)); + | ^^^ expected slice `[u8]`, found `i32` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/generic-associated-types/issue-76535.rs b/src/test/ui/generic-associated-types/issue-76535.rs new file mode 100644 index 0000000000000..2b4757d8d15ed --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-76535.rs @@ -0,0 +1,41 @@ +#![feature(generic_associated_types)] + //~^ WARNING the feature + +pub trait SubTrait {} + +pub trait SuperTrait { + type SubType<'a>: SubTrait; + //~^ ERROR missing generics for associated + + fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; +} + +pub struct SubStruct<'a> { + sup: &'a mut SuperStruct, +} + +impl<'a> SubTrait for SubStruct<'a> {} + +pub struct SuperStruct { + value: u8, +} + +impl SuperStruct { + pub fn new(value: u8) -> SuperStruct { + SuperStruct { value } + } +} + +impl SuperTrait for SuperStruct { + type SubType<'a> = SubStruct<'a>; + + fn get_sub<'a>(&'a mut self) -> Self::SubType<'a> { + SubStruct { sup: self } + } +} + +fn main() { + let sub: Box> = Box::new(SuperStruct::new(0)); + //~^ ERROR the trait + //~| ERROR the trait +} diff --git a/src/test/ui/generic-associated-types/issue-76535.stderr b/src/test/ui/generic-associated-types/issue-76535.stderr new file mode 100644 index 0000000000000..ce4875af9c012 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-76535.stderr @@ -0,0 +1,63 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-76535.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0107]: missing generics for associated type `SuperTrait::SubType` + --> $DIR/issue-76535.rs:7:10 + | +LL | type SubType<'a>: SubTrait; + | ^^^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-76535.rs:7:10 + | +LL | type SubType<'a>: SubTrait; + | ^^^^^^^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type SubType<'a><'a>: SubTrait; + | ^^^^ + +error[E0038]: the trait `SuperTrait` cannot be made into an object + --> $DIR/issue-76535.rs:38:14 + | +LL | let sub: Box> = Box::new(SuperStruct::new(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object + | + = help: consider moving `get_sub` to another trait +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-76535.rs:10:37 + | +LL | pub trait SuperTrait { + | ---------- this trait cannot be made into an object... +... +LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; + | ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type + +error[E0038]: the trait `SuperTrait` cannot be made into an object + --> $DIR/issue-76535.rs:38:57 + | +LL | let sub: Box> = Box::new(SuperStruct::new(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object + | + = help: consider moving `get_sub` to another trait +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-76535.rs:10:37 + | +LL | pub trait SuperTrait { + | ---------- this trait cannot be made into an object... +... +LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; + | ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type + = note: required because of the requirements on the impl of `CoerceUnsized>>>` for `Box` + = note: required by cast to type `Box>>` + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/generic-associated-types/issue-79422.rs b/src/test/ui/generic-associated-types/issue-79422.rs new file mode 100644 index 0000000000000..26b38430dd9a5 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-79422.rs @@ -0,0 +1,47 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait RefCont<'a, T> { + fn t(&'a self) -> &'a T; +} + +impl<'a, T> RefCont<'a, T> for &'a T { + fn t(&'a self) -> &'a T { + self + } +} + +impl<'a, T> RefCont<'a, T> for Box { + fn t(&'a self) -> &'a T { + self.as_ref() + } +} + +trait MapLike { + type VRefCont<'a>: RefCont<'a, V>; + //~^ ERROR missing generics + fn get<'a>(&'a self, key: &K) -> Option>; +} + +impl MapLike for std::collections::BTreeMap { + type VRefCont<'a> = &'a V; + fn get<'a>(&'a self, key: &K) -> Option<&'a V> { + std::collections::BTreeMap::get(self, key) + } +} + +struct Source; + +impl MapLike for Source { + type VRefCont<'a> = Box; + fn get<'a>(&self, _: &K) -> Option> { + Some(Box::new(V::default())) + } +} + +fn main() { + let m = Box::new(std::collections::BTreeMap::::new()) + as Box>>; + //~^ ERROR the trait + //~^^^ ERROR the trait +} diff --git a/src/test/ui/generic-associated-types/issue-79422.stderr b/src/test/ui/generic-associated-types/issue-79422.stderr new file mode 100644 index 0000000000000..d2e12962715f0 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-79422.stderr @@ -0,0 +1,54 @@ +error[E0107]: missing generics for associated type `MapLike::VRefCont` + --> $DIR/issue-79422.rs:21:10 + | +LL | type VRefCont<'a>: RefCont<'a, V>; + | ^^^^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-79422.rs:21:10 + | +LL | type VRefCont<'a>: RefCont<'a, V>; + | ^^^^^^^^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type VRefCont<'a><'a>: RefCont<'a, V>; + | ^^^^ + +error[E0038]: the trait `MapLike` cannot be made into an object + --> $DIR/issue-79422.rs:44:12 + | +LL | as Box>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object + | + = help: consider moving `get` to another trait +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-79422.rs:23:38 + | +LL | trait MapLike { + | ------- this trait cannot be made into an object... +... +LL | fn get<'a>(&'a self, key: &K) -> Option>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type + +error[E0038]: the trait `MapLike` cannot be made into an object + --> $DIR/issue-79422.rs:43:13 + | +LL | let m = Box::new(std::collections::BTreeMap::::new()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object + | + = help: consider moving `get` to another trait +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-79422.rs:23:38 + | +LL | trait MapLike { + | ------- this trait cannot be made into an object... +... +LL | fn get<'a>(&'a self, key: &K) -> Option>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type + = note: required because of the requirements on the impl of `CoerceUnsized + 'static)>>>` for `Box>` + = note: required by cast to type `Box + 'static)>>` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/generic-associated-types/issue-80433-reduced.rs b/src/test/ui/generic-associated-types/issue-80433-reduced.rs new file mode 100644 index 0000000000000..7c1673edc51a4 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-80433-reduced.rs @@ -0,0 +1,24 @@ +// check-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +struct E {} + +trait TestMut { + type Output<'a>; + fn test_mut(&mut self) -> Self::Output<'static>; +} + +impl TestMut for E { + type Output<'a> = usize; + fn test_mut(&mut self) -> Self::Output<'static> { + todo!() + } +} + +fn test_simpler<'a>(_: impl TestMut = usize>) {} + +fn main() { + test_simpler(E {}); +} diff --git a/src/test/ui/generic-associated-types/issue-80433.rs b/src/test/ui/generic-associated-types/issue-80433.rs new file mode 100644 index 0000000000000..ea65f05de23d7 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-80433.rs @@ -0,0 +1,35 @@ +#![feature(generic_associated_types)] +#![allow(incomplete_features)] + +#[derive(Default)] +struct E { + data: T, +} + +trait TestMut { + type Output<'a>; + //~^ ERROR missing generics + fn test_mut<'a>(&'a mut self) -> Self::Output<'a>; +} + +impl TestMut for E +where + T: 'static, +{ + type Output<'a> = &'a mut T; + fn test_mut<'a>(&'a mut self) -> Self::Output<'a> { + &mut self.data + } +} + +fn test_simpler<'a>(dst: &'a mut impl TestMut) +{ + for n in 0i16..100 { + *dst.test_mut() = n.into(); + } +} + +fn main() { + let mut t1: E = Default::default(); + test_simpler(&mut t1); +} diff --git a/src/test/ui/generic-associated-types/issue-80433.stderr b/src/test/ui/generic-associated-types/issue-80433.stderr new file mode 100644 index 0000000000000..5398920fafdb0 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-80433.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for associated type `TestMut::Output` + --> $DIR/issue-80433.rs:10:10 + | +LL | type Output<'a>; + | ^^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-80433.rs:10:10 + | +LL | type Output<'a>; + | ^^^^^^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type Output<'a><'a>; + | ^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs index e203a5e0d2de6..2d38770bcdff8 100644 --- a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs +++ b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs @@ -1,10 +1,14 @@ #![feature(generic_associated_types)] + //~^ the feature `generic_associated_types` is incomplete trait X { type Y<'a>; + //~^ ERROR this associated type + //~| ERROR this associated type } const _: () = { fn f2<'a>(arg : Box = &'a ()>>) {} - //~^ ERROR: generic associated types in trait paths are currently not implemented }; + +fn main() {} diff --git a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr index e59a72a99eeb9..60b8fb9bcaa23 100644 --- a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr +++ b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr @@ -1,8 +1,49 @@ -error: generic associated types in trait paths are currently not implemented - --> $DIR/trait-path-type-error-once-implemented.rs:8:30 +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/trait-path-type-error-once-implemented.rs:1:12 | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^^^ +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/trait-path-type-error-once-implemented.rs:5:10 + | +LL | type Y<'a>; + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/trait-path-type-error-once-implemented.rs:5:10 + | +LL | type Y<'a>; + | ^ -- +help: add missing lifetime argument + | +LL | fn f2<'a>(arg : Box = &'a ()>>) {} + | ^^ + +error[E0107]: this associated type takes 0 const arguments but 1 const argument was supplied + --> $DIR/trait-path-type-error-once-implemented.rs:5:10 + | +LL | type Y<'a>; + | __________^- + | | | + | | expected 0 const arguments +LL | | +LL | | +LL | | } +LL | | +LL | | const _: () = { +LL | | fn f2<'a>(arg : Box = &'a ()>>) {} + | |________________________________- help: remove these generics + | +note: associated type defined here, with 0 const parameters + --> $DIR/trait-path-type-error-once-implemented.rs:5:10 + | +LL | type Y<'a>; + | ^ -error: aborting due to previous error +error: aborting due to 2 previous errors; 1 warning emitted +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.rs b/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.rs deleted file mode 100644 index 02d53d5faeec5..0000000000000 --- a/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![feature(generic_associated_types)] - -trait X { - type Y<'a>; -} - -const _: () = { - fn f1<'a>(arg : Box = &'a ()>>) {} - //~^ ERROR: generic associated types in trait paths are currently not implemented -}; - -const _: () = { - fn f1<'a>(arg : Box>) {} - //~^ ERROR: lifetime in trait object type must be followed by `+` -}; - -fn main() {} diff --git a/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.stderr b/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.stderr deleted file mode 100644 index 1fba9cebd2491..0000000000000 --- a/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: lifetime in trait object type must be followed by `+` - --> $DIR/trait-path-unimplemented.rs:13:31 - | -LL | fn f1<'a>(arg : Box>) {} - | ^^ - -error: generic associated types in trait paths are currently not implemented - --> $DIR/trait-path-unimplemented.rs:8:30 - | -LL | fn f1<'a>(arg : Box = &'a ()>>) {} - | ^^^^ - -error: aborting due to 2 previous errors - From 0c3a7d8b8598ef792995a9173dfa569fff445568 Mon Sep 17 00:00:00 2001 From: Jacob Hughes Date: Thu, 4 Feb 2021 19:02:57 -0500 Subject: [PATCH 24/26] Update LayoutError/LayoutErr stability attributes --- library/core/src/alloc/layout.rs | 4 ++-- library/core/src/alloc/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index c572c66ce328b..9dc3f05dae5ac 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -400,7 +400,7 @@ impl Layout { #[stable(feature = "alloc_layout", since = "1.28.0")] #[rustc_deprecated( - since = "1.51.0", + since = "1.52.0", reason = "Name does not follow std convention, use LayoutError", suggestion = "LayoutError" )] @@ -409,7 +409,7 @@ pub type LayoutErr = LayoutError; /// The parameters given to `Layout::from_size_align` /// or some other `Layout` constructor /// do not satisfy its documented constraints. -#[stable(feature = "alloc_layout_error", since = "1.49.0")] +#[stable(feature = "alloc_layout_error", since = "1.50.0")] #[derive(Clone, PartialEq, Eq, Debug)] pub struct LayoutError { private: (), diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 045eb58d0135a..c1c993bbc51af 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -11,14 +11,14 @@ pub use self::global::GlobalAlloc; pub use self::layout::Layout; #[stable(feature = "alloc_layout", since = "1.28.0")] #[rustc_deprecated( - since = "1.51.0", + since = "1.52.0", reason = "Name does not follow std convention, use LayoutError", suggestion = "LayoutError" )] #[allow(deprecated, deprecated_in_future)] pub use self::layout::LayoutErr; -#[stable(feature = "alloc_layout_error", since = "1.49.0")] +#[stable(feature = "alloc_layout_error", since = "1.50.0")] pub use self::layout::LayoutError; use crate::fmt; From 4253919f1d579f453aaeb76e5824b11207b52ee0 Mon Sep 17 00:00:00 2001 From: Tyson Nottingham Date: Thu, 4 Feb 2021 18:38:06 -0800 Subject: [PATCH 25/26] Indicate change in RSS from start to end of pass in time-passes output Previously, this was omitted because it could be misleading, but the functionality seems too useful not to include. --- .../rustc_data_structures/src/profiling.rs | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 9a85b9d02c995..f0b413c795e9c 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -590,24 +590,21 @@ pub fn print_time_passes_entry( end_rss: Option, ) { let rss_to_mb = |rss| (rss as f64 / 1_000_000.0).round() as usize; + let rss_change_to_mb = |rss| (rss as f64 / 1_000_000.0).round() as i128; let mem_string = match (start_rss, end_rss) { (Some(start_rss), Some(end_rss)) => { - // It's tempting to add the change in RSS from start to end, but its somewhat confusing - // and misleading when looking at time-passes output. Consider two adjacent entries: - // - // time: 10.000; rss start: 1000MB, end: 1000MB, change: 0MB pass1 - // time: 5.000; rss start: 2000MB, end: 2000MB, change: 0MB pass2 - // - // If you're looking for jumps in RSS based on the change column, you miss the fact - // that a 1GB jump happened between pass1 and pass2 (supposing pass1 and pass2 actually - // occur sequentially and pass1 isn't just nested within pass2). It's easy to imagine - // someone missing this or being confused by the fact that the change is zero. - - format!("; rss: {:>5}MB -> {:>5}MB", rss_to_mb(start_rss), rss_to_mb(end_rss)) + let change_rss = end_rss as i128 - start_rss as i128; + + format!( + "; rss: {:>4}MB -> {:>4}MB ({:>+5}MB)", + rss_to_mb(start_rss), + rss_to_mb(end_rss), + rss_change_to_mb(change_rss), + ) } - (Some(start_rss), None) => format!("; rss start: {:>5}MB", rss_to_mb(start_rss)), - (None, Some(end_rss)) => format!("; rss end: {:5>}MB", rss_to_mb(end_rss)), + (Some(start_rss), None) => format!("; rss start: {:>4}MB", rss_to_mb(start_rss)), + (None, Some(end_rss)) => format!("; rss end: {:>4}MB", rss_to_mb(end_rss)), (None, None) => String::new(), }; From 573f1c059fe290d719fc444e3a3316f6954af578 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 5 Feb 2021 11:48:43 +0100 Subject: [PATCH 26/26] Fix `install-awscli.sh` error in CI. --- src/ci/scripts/install-awscli.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/scripts/install-awscli.sh b/src/ci/scripts/install-awscli.sh index f9b759fe343f0..3d8f0de7a396b 100755 --- a/src/ci/scripts/install-awscli.sh +++ b/src/ci/scripts/install-awscli.sh @@ -27,7 +27,7 @@ if isLinux; then pip="pip3" pipflags="--user" - sudo apt-get install -y python3-setuptools + sudo apt-get install -y python3-setuptools python3-wheel ciCommandAddPath "${HOME}/.local/bin" fi